1、了解标准c库fopen等用法(点击跳转)
2、fputc写一个字符到文件
#include <stdio.h>
int main()
{
FILE *fp;
fp = fopen("./test.txt","w+");
//int fputc(int c, FILE *stream);
fputc('a',fp);
fclose(fp);
return 0;
}
3、fputc写一个字符串到文件
3.1、错误示例,小细节。
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char *str = "wenjian chu ru men !";
int i = 0;
fp = fopen("./test.txt","w+");
for(i=0;i<strlen(str);i++){
//int fputc(int c, FILE *stream);
fputc(*str,fp);
str++; //一个一个字符往文件里面写入
}
fclose(fp);
return 0;
}
问:为什么不能全部写入进去?
因为 for循环里面 i < strlen(str) 在变 。在变小,每打印一次往后偏移了一位呀。
3.2、正确示例
在 for 循环之前先计算字符串的长度,这一小细节,即可避免写入不完全。
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char *str = "wenjian chu ru men !";
int i = 0;
int len = strlen(str);
fp = fopen("./test.txt","w+");
for(i=0;i<len;i++){
//int fputc(int c, FILE *stream);
fputc(*str,fp);
str++; //一个一个字符往文件里面写入
}
fclose(fp);
return 0;
}
4、fgetc,feof
fgetc :意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。
返回值,是返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF。虽然返回一个字节,但返回值不为unsigned char的原因为,返回值要能表示-1(即为EOF)。
feof :其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0
注意:feof 判断文件结束是通过读取函数fread/fscanf等返回错误来识别的,故而判断文件是否结束应该是在读取函数之后进行判断。比如,在while循环读取一个文件时,如果是在读取函数之前进行判断,则如果文件最后一行是空白行,可能会造成内存错误。
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char c;
fp = fopen("./test.txt","r"); //权限给 "r" 以只读方式打开文件,该文件必须存在。
while(!feof(fp)){
c = fgetc(fp);
printf("%c",c);
}
fclose(fp);
printf("\n");
return 0;
}
可以看到,程序输出的结果比txt文件的字符多出了一个?符号。
4.1解决
以下内容摘录,原文链接:https://blog.csdn.net/weixin_43667437/article/details/108920944
经过查阅相关资料发现,fgetc函数在,传入参数fp到达文件末尾的时候,会返回一个EOF,这个EOF的实值是-1。
那么会不会是fgetc函数多输出了一遍呢?循环到达文件末尾没有停止,而是把最后的EOF也输出了?
添加两行代码,实验一下:
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char c;
fp = fopen("./test.txt","r"); //权限给 "r" 以只读方式打开文件,该文件必须存在。
putchar(-1);
printf("\n");
while(!feof(fp)){
c = fgetc(fp);
printf("%c",c);
}
fclose(fp);
printf("\n");
return 0;
}
-1 的输出结果果然就是这个?符号,也就是说,循环多走了一遍,才结束,导致EOF被当作字符输出了。
在查阅相关资料后得到如下的经验:
feof函数的判断方法不是判断当前指针是否指向文件末尾,而是根据上一次读取的返回值进行判断,如果上一次读取的返回值为EOF,那么feof(fp)为真,否则为假。
而fgetc函数的方法刚好是:先读取当前指针指向的内容,再让指针向后移。
这样一来,刚好,如果两者放在一起操作,就会发生多读一个EOF的现象:
getc在读到txt文档最后一个字符的时候,fp指向最后一个字符,读出字符后,fp向后移,fp指向EOF,进行下一次循环,feof判断是否到达文档末尾:由于上一次fgetc读出的是文档最后一个字符,所以即使fp当前已经指向了EOF,feof函数还是会返回假,这样循环就又继续了,下一次循环中,就会将fp指向的EOF输出,fp后移(已经到达文档尾,无法后移);
再次修改代码:
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char c;
fp = fopen("./test.txt","r"); //以只读方式打开文件,该文件必须存在。
c = fgetc(fp);
while(!feof(fp)){
printf("%c",c);
c = fgetc(fp);
}
fclose(fp);
printf("\n");
return 0 ;
}
输出结果正常