今天练习代码的时候碰见这样一个问题:
一个文件test.txt,文件内容为
1
2
4
5
在程序中读写这个文件,修改其内容,添加一行,将文件内容变成:
1
2
3
4
5
楼主的错误代码是这样的:
1 #include<stdio.h> 2 #include<string.h> 3 4 int main(int argc, const char *argv[]) 5 { 6 FILE *fp,*fd; 7 fp = fopen("text.txt","r"); 8 fd = fopen("text1.txt","w"); 9 char a; 10 int line=0; 11 while((a=(char)fgetc(fp)) > 0) 12 { 13 fputc(a,fd); 14 if(a == '\n') 15 { 16 line++; 17 if(line==2) 18 { 19 fputc('3',fd); 20 fputc('\n',fd); 21 } 22 } 23 } 24 // fflush(fp); 25 // fflush(fd); 26 close(fp); 27 close(fd); 28 printf("re\n"); 29 if((fp = fopen("text.txt","w")) == NULL) 30 { 31 printf("fp error\n"); 32 return -1; 33 } 34 if((fd = fopen("text1.txt","r")) == NULL) 35 { 36 printf("fd errpr\n"); 37 return -1; 38 } 39 while((a = (char)fgetc(fd)) > 0) 40 { 41 printf("enter\n"); 42 fputc(a,fp); 43 } 44 printf("%d\n",a); 45 close(fp); 46 close(fd); 47 return 0; 48 }
这样编译运行,text1.txt 中 的内容是 1 2 3 4 5
但是text.txt 中会没内容。笔者烦恼了一会,之后想起来,标准IO是带缓冲区的,应该是缓冲区这里出毛病了,在程序中加了刷新缓冲区,程序就正常了。(就是将上述程序中的两个注释去掉就可以了。)
原因如下:采用标准IO打开文件采用的是全缓冲区,等到程序结束 或者 缓冲区满 或者 手动刷新才会将缓冲区中的内容取出。
在第一次打开并读取完text.txt时,缓冲区的内容是这样 1 \n 2 \n 4 \n 5 \n -1(这里负一代表文件末尾了,具体解释请 MAN fgetc),在关闭IO流之后(未刷新),在打开IO流,缓冲区中的数据依然存在,此时在读取text1.txt中的数据,笔者猜测缓冲区的数据应该是这样的 1\n 2\n 4\n 5\n -1,因为之前读到 -1时并没有在往下读数据了,此时缓冲区的位置符仍然停留在-1处,在第二次读取时直接读的负一然后循环就不执行了,就无法向text.txt中赋值数据,又因为text.txt是写打开的,所以里面就会没有数据。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
找到问题了,因为标准IO有缓冲区,实际上在程序运行时,并没有将数据写入TEXT1.TXT 也就是说其中并没有内容。之所以最后在text1.txt中看到了数据,是因为程序结束了,缓冲区中的数据才写入了text1.txt。