文本文件的读写是算法研究和工程应用中常见的功能模块。C和C++的标准库中提供了多种文本文件的读写方法,我们一般都会掌握其中比较习惯使用的一种或几种方法。解决问题的方法不在多,而在精。经过在网上的资料搜索和总结,这里我对实际编程中经常用到的几类方法总结如下。对C和C++分开介绍,目的是让大家即能用C++读写文本文件,又能用C读写文本文件。不多不少,恰到好处地掌握好该掌握的读写知识。
文本文件内容:后面在代码示例中读入的文本文件text.txt的内容如下:
Never give up, it's truth.
0: 12 34
这里我们使用简捷好用的流式文件操作,即FILE结构,需要加入头文件fstream.h。可以通过FILE *fopen(const char *filename,const char *mode)
打开文件流。其中,参数filename指向要打开的文件名,mode表示打开状态的字符串,其取值如下:
下面通过特别设置的实例对相应的函数进行介绍和说明。
函数fscanf的格式控制非常方便,基本上能应对所有的文本文件读取任务。有时候为了更便捷,需要使用某些特定功能的函数:
int fseek(FILE *stream, long offset, int whence)
此函数一般用于二进制模式打开的文件中,功能是定位到流中指定的位置。参数offset是移动的字符数,whence是移动的基准可取值为:SEEK_SET 0 文件开头;SEEK_CUR 1 当前读写的位置;SEEK_END 2 文件尾部。
char *fgets(char *s, int n, FILE *stream)
此函数表示从流中读一行或指定个字符(n-1),参数s是来接收字符串,如果成功则返回s的指针,否则返回NULL。
string filePath = "text.txt";
FILE *fp = fopen(filePath.c_str(), "r");
if (fp == nullptr)
{
cout<<"Invalid file path\n";
return;
}
char str[512];
fscanf(fp, "%s", &str);
int offset = sizeof(char)*9;
fseek(fp, offset, 1);
char str1[512];
int n = 12;
fgets(str1, n+1, fp);
cout<int no, k1, k2;
fscanf(fp, "%d%s%d%d", &no, &str, &k1, &k2);
cout<" "<" "<
函数fprintf主要要掌握的就是对于输出格式的控制,语法规则是百分符号%+代表类型的字母,格式控制就写在二者之间。
下列代码中,%6.2lf
表示以6个字符宽度、2位小数的精度输出;%03d
表示以3个字符宽度不足部分以0填充的格式输出。
string filePath = "text.txt";
FILE *fp = fopen(filePath.c_str(), "a");
if (fp == nullptr)
{
cout<<"Invalid file path\n";
return;
}
int a = 91;
fprintf(fp, "C appending %03d\n", a);
double k = 192.3345;
fprintf(fp, "%6.2lf\n", k);
fclose(fp);
相比文本文件而言,二进制文件的读写不需要考虑输出格式的相关问题。原因有二,一是二进制文件内容是用户看不懂的二进制字节;二是二进制文件的读写操作都是按字节个数读取的,无需顾及格式。所以,写二进制文件的时候千万不要输出那些格式控制相关的字符,如\n
,那样徒增数据读取的难度,百害而无一益。
函数fread的原型是size_t fread(void ptr, size_t size, size_t n, FILE *stream),参数ptr是保存读取的数据,void的指针可用任何类型的指针来替换,如char*、int *等来替换;size是每块的字节数;n是读取的块数,如果成功,返回实际读取的块数(不是字节数)。
string filePath = "binary.bin";
FILE *fp = fopen(filePath.c_str(), "rb");
int intSize = sizeof(int);
int charSize = sizeof(char);
char *buffer1 = new char[13];
int *buffer2 = new int[3];
fread(buffer1, charSize, 13, fp);
fread(buffer2, intSize, 3, fp);
cout<cout<0]<<" "<1]<<" "<2]<
函数fwrite的形参类型与上文提到的函数fread的形参类型一致,此处不再赘述。
string filePath = "binary.bin";
FILE *fp = fopen(filePath.c_str(), "wb");
int intSize = sizeof(int);
int charSize = sizeof(char);
int doubleSize = sizeof(double);
char *buffer1 = "Hello, world!";
int *buffer2 = new int[3];
buffer2[0] = 0; buffer2[1] = 12; buffer2[2] = 34;
double *buffer3 = new double[1];
buffer3[0] = 192.3;
fwrite(buffer1, charSize, 13, fp);
fwrite(buffer2, intSize, 3, fp);
fwrite(buffer3, doubleSize, 1, fp);
fclose(fp);
在C++中,对文件的操作是通过stream的子类fstream来实现的。要用这种方式操作文件,就必须加入头文件fstream.h。。
函数open的原型是*void open(const char filename,int mode,int access)。参数filename:要打开的文件名;参数mode:要打开文件的方式;access:打开文件的属性。打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下(可以用“|”或者“+”把以下属性连接起来):
另外,此处代码中的函数seekg和getline的用法和功能与C读写函数中的fseek和fgets类似,故略之。
string filePath = "text.txt";
ifstream fin;
fin.open(filePath.c_str(), ios::in);
char str[512];
fin>>str;
int offset = 9;
fin.seekg(offset, ios::cur);
int n = 12;
char str1[512];
fin.getline(str1, n+1);
cout<int no, k1, k2;
fin>>no;
int n = 2; //! to skip ':' and ' '
fin.seekg(n+1, ios::cur);
fin>>k1>>k2;
cout<<no<<" "<" "<close();
在C++语法中,文本文件输出函数的重点也是对输出格式的控制。这里是通过调用标准库中相应的输出格式设置函数来实现的,调用时需要包含头文件iomanip.h。比较常用的格式控制函数有:字符宽度设置函数setw;默认填充字符设置函数setfill;输出精度设置函数setprecision。具体的用法如下列代码中的调用方法。
string filePath = "text.txt";
ofstream fout;
fout.open(filePath.c_str(), ios::app | ios::_Nocreate);
char str[512] = "C++ appending ";
fout<<str;
fout<<0<<" : "<12<<" "<34<3)<'0')<<91<<" ";
double k = 192.9773;
fout<6)<
在C++中,对二进制的读写是通过函数read和write来实现。这组函数的用法和功能与C中的函数fread和fwrite相一致,这里不再做过多介绍。值得注意的是,函数的第一个形参类型必须是 unsigned char *,因此当数据的真实类型不是unsigned char时,需要进行类型转换。
string filePath = "binary.bin";
ifstream fin;
fin.open(filePath.c_str(), ios::binary);
int intSize = sizeof(int);
int charSize = sizeof(char);
char *buffer1 = new char[13];
char *buffer2 = new char[3*intSize];
fin.read(buffer1, charSize*13);
fin.read(buffer2, intSize*3);
cout<cout<<(int)buffer2[0]<<" "<<(int)buffer2[1]<
string filePath = "binary.bin";
ofstream fout;
fout.open(filePath.c_str(), ios::binary);
int intSize = sizeof(int);
int charSize = sizeof(char);
int doubleSize = sizeof(double);
char *buffer1 = "Hello, world!";
char *buffer2 = new char[3*intSize];
buffer2[0] = 0; buffer2[1] = 12; buffer2[2] = 34;
char *buffer3 = new char[doubleSize*1];
buffer3[0] = 192.3;
fout.write(buffer1, charSize*13);
fout.write(buffer2, intSize*3);
fout.write(buffer3, doubleSize*1);
fout.close();
本文总结了C和C++中常用的读写文本文件和二进制文件的函数。目的是为C/C++初学者提供一份简单实用、详略得当的关于文件读写的学习资料。当然,要真正掌握其用法,还必须是亲身实践和多次练习,实践出真知!