2.3 fscanf函数和fprintf函数
前面说过,fscanf函数和fprintf函数是格式化输入输出函数。什么是格式化函数呢?
其实格式化函数就是对于不同格式的数据都能够进行输入输出,比如:整型,浮点型,结构体类型等等,这些就是不同格式的数据。
相较于scanf和printf函数,fscanf函数和fprintf只是多了一个参数,即FILE指针所指向的文件。fscanf函数是向FILE的指针指向的文件中读取格式化的数据,fprintf函数是向FILE*的指针指向的文件中写入格式化的数据。
对比如下:
int fscanf ( FILE * stream, const char * format, ... ); int scanf ( const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... ); int printf ( const char * format, ... );
举一个简单的例子:
向text.txt文件中写入结构体数据
int main() { FILE* pf = fopen("text.txt", "w"); if (pf == NULL) { perror("fopen"); return 0; } struct S { char name[20]; int age; float score; }s = {"zhangsan",20,99.5f}; fprintf(pf,"%s %d %f", s.name, s.age, s.score); fclose(pf); pf = NULL; return 0; }
运行成功后,文件中就有了该结构体的数据。
对于fscanf来说亦是如此:
以读的方式打开该文件,对其中的数据进行读取。读取后,打印出来看即可。
s.name不用&的原因是,s.name是一个数组名,表示首元素地址,不需要&,而其他的age和score则需要&。
前面说过,这几个函数都是适用于所有输入流输出流,那么就包括了键盘(标准输入流),屏幕(标准输出流)。
int main() { int ch = fgetc(stdin); fputc(ch, stdout); }
此时,我们会从键盘中读取一个字符,写入到屏幕中。
对于其他函数也是如此。仍可以从键盘中读取数据,写入到屏幕上。
2.4 fwrite函数和fread函数
上面提到,fwrite函数和fread函数是以二进制的形式进行写入和读取的。
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
先来看看fwrite在库中的声明。
fwrite函数是向stream这个流中一次写count个大小为size的ptr指向的内容。
看不懂没关系,举个例子:
typedef struct S { char name[20]; int age; float score; }S; int main() { S s = { "zhangsan",20,95.5f }; FILE* pf = fopen("text.txt", "wb"); if (pf == NULL) { perror("fopen"); return 0; } fwrite(&s, sizeof(S), 1, pf); fclose(pf); pf = NULL; return 0; }
此时我们创建了一个结构体,该结构体有三个成员,我们以二进制写入的形式打开文件进行写入,此时向pf指向的文件中写入s这块空间,一次写入1个sizeof(S)大小的内容。
运行成功后,打开text.txt文件:
你会发现出了拼音zhangsan,其他的都看不懂,没关系,因为这是二进制形式。
看不懂并不代表代码是错误的。
既然我们看不懂,我们就让编译器来看,下面我们以二进制读取的方式,向文件中读取数据出来。
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
既然是读取,那么就是跟写入相反而已。
从stream流指向的文件中读取ptr这块空间的内容,一次读取count个大小为size个字节的内容。
typedef struct S { char name[20]; int age; float score; }S; int main() { S s = { 0 }; FILE* pf = fopen("text.txt", "rb"); if (pf == NULL) { perror("fopen"); return 0; } fread(&s, sizeof(S), 1, pf); printf("%s %d %f", s.name, s.age, s.score); fclose(pf); pf = NULL; return 0; }
此时我们向pf流指向的文件中读取s这块空间的内容,一次读取1个大小为sizeof(S)个字节的内容。读取成功后,我们就打印出来看看。
打印结果确实符合预期。
总结:fwrite 和fread函数是向文件中以二进制的形式写入和读取文件的。