fgets函数
fgets(字符数组名,n,文件指针)
该函数的作用是从指定文件中读一个字符串到字符数组中,n表示所得到的字符串中字符的个数(包含字符"\0")
要知道在上边我们在filecom里写进了hello world!
int main() { FILE* fp; char str[30]; if ((fp = fopen("filecom", "r")) == NULL) { perror("fopen error"); } fgets(str, 11, fp); printf("%s", str); return 0; }
💭运行后如图
上面所说包含"\0",在这里我们打印11个字符,然而这里直有10个字符(包含空格),这是因为"\0"也占了一个字符位。
fprintf函数和fscanf函数
我们对printf函数和scanf应该都已经很熟悉了,下面要讲解的fprint和fscnaf与他们的作用相似,他们最大的区别就是读写的对象不同,fprintf和fscanf函数读写的对象不是终端,而是磁盘文件。
我们在cplusplus官网比较一番
相比较printf函数,fprintf多了一个参数,fprintf函数形式如下
fprintf(fp,"%d",i);
作用是将整型变量i的值以"%d"的格式输出到fp指向的文件中
💭举个梨子
int main() { FILE* fp; int i = 666; if ((fp = fopen("filenum", "w")) == NULL) { perror("fopen error"); } fprintf(fp, "%d", i); return 0; }
创建一个filenum文件,写入666;
运行结果如下:
⭐如果是%c写入呢,就要参考参照ASCII码表
fscanf函数
格式如下
fscanf(文件类型指针,格式字符串,输入列表);
fscanf(fp , "%d" , &i);
⭐我们先写入abcdefg
💡然后以字符的形式输出
运行后结果正常,输出为参照ASCII对应的数字。
sprintf和sscanf函数
前边已经了解了fprintf和fscanf函数
💡再对比前边的fprintf函数,相比于fprintf函数将内容写进文件中,可以发现sprintf函数的第一个参数变成了一个字符指针,sprintf的作用即是将格式化的数据转化成字符串,放在传进来的字符数组里。
举一个例子
typedef struct Nums { int a; char b; double c; }Nums; int main() { char str[30] = "0"; Nums nums = { 3,'f',1.5 }; sprintf(str, "%d %c %lf\n", nums.a, nums.b, nums.c); printf("%s", str); return 0; }
仔细观擦发现和printf函数差不多,作用也很相似。
sscanf同理
💡sscanf从字符串中读取格式化的数据。
typedef struct Nums { int a; char b; double c; }Nums; int main() { char str[30] = "0"; Nums nums = { 3,'f',1.5 }; Nums nums1 = { 0 }; sprintf(str, "%d %c %lf\n", nums.a, nums.b, nums.c); //printf("%s", str); sscanf(str, "%d %c %lf", &(nums1.a), &(nums1.b), &(nums1.c)); printf("%d %c %lf", nums.a, nums.b, nums.c); return 0; }
📖读取str内的元素放进nums1中去,此时再打印结构体变量nums1就会发现已经把str内的数据搬进nums1中啦。
二进制的读写函数
⭐前边所介绍的fputc和fgetc函数,每次只能读写文件的一个字符,但我们在编写程序的过程中常常需要对整块数据进行读写,例如,对一个结构体类型的变量值进行读写,下面进行fread和fwrite函数。
因为写进去的是二进制文件,所以当我们用记事本打开时,看到的都是乱码。
代码如下
typedef struct Nums { int a; char b; double c; char str[10]; }Nums; int main() { Nums nums = { 1,'c',1.5,"heihei"}; FILE* pf = fopen("data.txt", "wb"); if (pf == NULL) { perror("fopen"); return 1; } fwrite(&nums, sizeof(Nums), 1, pf); fclose(pf); return 0; }
运行后如下
👑接下来我们要将它使用fread再读出来,放进一个结构体中,再将其打印出来,将上边的代码改造一下
📜代码如下
typedef struct Nums { int a; char b; double c; char str[10]; }Nums; int main() { Nums nums = { 0 }; FILE* pf = fopen("data.txt", "rb"); if (pf == NULL) { perror("fopen"); return 1; } fread(&nums, sizeof(Nums), 1, pf); printf("%d %c %f %s\n", nums.a, nums.b, nums.c, nums.str); fclose(pf); return 0; }
👉运行后代码如下,我们将nums已经置空了,但打印结果已经说明了一切。
文件的定位
⭐学习了前边的函数,我们这时候又要思考了,在对文件进行操作时,一定要从头开始吗?多不方便哇,这时候就需要文件定位函数来实现对文件的随机读取。
fseek函数
fseek(文件类型指针,位移量,起始点);
这个函数的作用是移动文件内部的位置指针,其中,“文件类型指针”指向被移动的文件;“移动量”表示移动的字节数,要求位移量是long类型数据。“起始点”表示从何处开始计算位移量,规定的起始点有文件首,当前位置,文件末。
表示方法如图
🙉怎么用呢?
fseek(fp,-20,1);
fseek(fp,-20,SEEK_CUR);
代码表示将位置指针从当前位置向后退20个字节。
🙉看代码
int main() { FILE* file = fopen("data.txt", "w"); fputs("This is an apple.", file); fseek(file, 9, 0); fputs(" sam", file); fclose(file); return 0; }
⭐运行后如图
结合运行结果很容易发现,在替换时将空格也替换了,输入的位移量是九,在输入是从第十个位置继续输入,然后puts里的字符串覆盖原字符串。
fseek(fp,5,0);
💡 此代码的含义是将文件指针指向距离文件首5个字节的位置,也就是指向字符串中的第六个字符。
rewind函数
💭前边讲过了fseek函数,这里介绍的rewind函数也可以起到定位文件指针的作用
int rewind(文件类型指针);
该函数的作用是使位置指针重新返回文件的开头,该函数没有返回值。
举一个例子
int main() { FILE* fp; char ch; fp = fopen("data.txt", "r"); ch = fgetc(fp); while (ch != EOF) { putchar(ch); ch = fgetc(fp); } rewind(fp); ch = fgetc(fp); while (ch != EOF) { putchar(ch); ch = fgetc(fp); } fclose(fp); return 0; }
运行结果如图所示
有点懵?再来看一个例子
int main() { int n; FILE* pfile; char buffer[27]; pfile = fopen("myfile.txt", "w+"); for (n = 'A'; n <= 'Z'; n++) { fputc(n, pfile); } //rewind(pfile); fread(buffer, 1, 26, pfile); fclose(pfile); buffer[26] = '\0'; puts(buffer); return 0; }
可以看到将rewind注释掉后,运行结果如下,这是因为在使用fputc时将文件指针移动到了最后,再读的话就是从最后的位置开始读,所以输出结果为空。
如果将rewind解注释,再次运行
与上次运行的结果不同,此时将文件指针重新返回文件的开头,该函数没有返回值。
ftell函数
嘿嘿嘿,如果上边解释rewind大家还有点不懂,可以结合ftell函数来解释哦!
ftell函数一般形式如下
long ftell(文件类型指针)
该函数的作用是返回文件指针相对于起始位置的偏移量。
⭐利用同样的实例,来看一下是否rewind函数真的把文件指针搞到了最前边。同样也可以摸清ftell函数的作用。
int main() { int n; int size = 0; FILE* pfile; char buffer[27]; pfile = fopen("myfile.txt", "w+"); for (n = 'A'; n <= 'Z'; n++) { fputc(n, pfile); } size = ftell(pfile);//看一下此时的文件指针的位置 printf("%d\n", size); rewind(pfile);//指针退回到开头位置 size = ftell(pfile); printf("%d\n", size);//再看一次 fread(buffer, 1, 26, pfile); fclose(pfile); buffer[26] = '\0'; puts(buffer); return 0; }
运行后如图
我想已经很明显啦,到了这里文件操作相关的知识点就梳理完毕啦,如果有错误欢迎大家指出!