2. fgets与fputs
先来看看函数使用规则:
第一个参数为字符串地址,后面是文件指针,成功后,将返回非负值。出错时,该函数返回 EOF。
从流中读取字符并将其作为 C 字符串存储到 str 中,直到读取 (num-1) 个字符或到达换行符或文件结尾,以先发生者为准。
换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中。
终止空字符会自动追加到复制到 str 的字符之后。
例:
int main() { FILE* pf = fopen("WWT.text", "w"); if (pf == NULL) { perror("fopen"); return 1; } fputs("abcd\n", pf); fputs(" abc\n", pf); fclose(pf); pf = NULL; return 0; }
读取:
int main() { FILE* pf = fopen("WWT.text", "r"); if (pf == NULL) { perror("fopen"); return 1; } //fputs("abcd\n", pf); //fputs(" abc\n", pf); char arr[20]; fgets(arr, 8, pf); printf("%s", arr); fclose(pf); pf = NULL; return 0; }
输出:abcd
3. fscanf与fprintf
函数原型:
int fprintf ( FILE * stream, const char * format, ... );
我们可以对比printf:
int printf ( const char * format, ... );
我们知道 printf 就是将数据通过给定形式打印到屏幕上,那 fprintf 就应该是将数据通过特定形式打印到文件中。
再来看fscanf:
int fscanf ( FILE * stream, const char * format, ... );
同样的对比scanf:
int scanf ( const char * format, ... );
scanf就是通过键盘将数据通过特定形式输入内存中去,那 fscanf 应该就是将文件的数据通过特定形式输出到内存中去。
例:
struct S { char name[20]; int age; }; int main() { FILE* pf = fopen("WWT.text", "w"); if (pf == NULL) { perror("fopen"); return 1; } struct S s = { "zhangsan",29 }; fprintf(pf, "%s %d", s.name, s.age); //通过特定形式将特定数据写入pf所指向的文件中 fclose(pf); pf = NULL; return 0; }
读文件:
struct S { char name[20]; int age; }; int main() { FILE* pf = fopen("WWT.text", "r"); if (pf == NULL) { perror("fopen"); return 1; } //struct S s = { "zhangsan",29 }; //fprintf(pf, "%s %d", s.name, s.age); struct S w; fscanf(pf, "%s %d", w.name, &(w.age)); //将pf中的数据通过特定形式拿出来,放到指定位置 printf("%s %d", w.name, w.age); fclose(pf); pf = NULL; return 0; }
输出:zhangsan 29
3.1 sscanf与sprintf
这两个函数其实也是输入输出函数,具体如何用呢?我们来看:
int sprintf ( char * str, const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );
通过对比我们发现它们的差异只在第一个参数,前者是字符串指针,后者是文件指针,由此我们可以得出,该函数是将数据通过计算写入字符串中,那sscanf 就是将字符串中的数据读出来。
由此,实例如下:
struct S { char name[20]; int age; float score; }; int main() { struct S s = { "zhangsan", 20, 95.5f }; char arr[30] = { 0 }; //将数据以特定形式写入字符串 sprintf(arr, "%s %d %f", s.name, s.age, s.score); printf("%s\n", arr); struct S w = { 0 }; //将arr中的数据以特定形式输出到特定变量中 sscanf(arr, "%s %d %f", w.name, &(w.age), &(w.score)); printf("%s %d %f\n", w.name, w.age, w.score); return 0; }
输出:
3.2 fread与fwrite
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
ptr 是指向要写入的元素数组的指针,
size 是要写入的每个元素的大小,
count 是元素数,每个元素的大小为字节大小,
stream 是指向指定输出流的 FILE 对象的指针。
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
ptr 是指向大小至少为(大小 * 计数)字节的内存块的指针,转换为 void *。
size 是要读取的每个元素的大小(以字节为单位)
count 是元素数,每个元素的大小为字节大小。
stream 是指向指定输入流的 FILE 对象的指针。
例:
struct S { char name[20]; int age; float score; }; int main() { struct S s = { "zhangsan", 20, 95.5f }; //把s中的数据写到文件中 FILE*pf = fopen("test.txt", "wb"); //"wb"以二进制读写形式打开 if (NULL == pf) { perror("fopen"); return 1; } //二进制的写文件 fwrite(&s, sizeof(s), 1, pf); //将s里的数据通过计算写入pf中 fclose(pf); pf = NULL; return 0; }
struct S { char name[20]; int age; float score; }; int main() { struct S s = { "zhangsan", 20, 95.5f }; FILE* pf = fopen("test.txt", "rb"); if (NULL == pf) { perror("fopen"); return 1; } 二进制的写文件 //fwrite(&s, sizeof(s), 1, pf); //二进制的读文件 struct S w; fread(&w, sizeof(w), 1, pf); //将pf里的数据通过计算写入w中 printf("%s %d %f", w.name, w.age, w.score); fclose(pf); pf = NULL; return 0; }
输出:zhangsan 20 95.500000