#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char c;
if((fp=fopen("test.txt","r+"))==NULL) // test文档中存放的为一些大小写混合字母
{
printf("Can not open file!\n");
exit(0);
}
while(!feof(fp))
{
c=fgetc(fp);
if(islower(c)!=0)
{
c=toupper(c);
fseek(fp,-1L,SEEK_CUR);
fputc(c,fp); //system("pause"); 可以加这句话测试fputc是有缓冲的,在程序暂停时,打开文件查看,这时转换后的大写字符还没有写入文件。
fseek(fp,0L,SEEK_CUR); //可以用后面讲的2种方法替代
}
}
return 0;
} 1、fflush(fp); 2、fpos_t pos; fgetpos( fp, &pos ); fsetpos( fp, &pos ); 上述代码是用来实现将文档中的小写字母转换为大写字母,代码中黑体那句fseek(fp,0L,SEEK_CUR); 表面上理解是将fp这个文件指针以当前位置为基准,正向偏移0个字节,也就是说不动。看上去好像没用的样子,可删了之后却出错了,我跟踪了下,发现文件指针第一次到了fpuc后就不能再后移了,就一直往文件里写,而feof()读不到文件的结尾,如果你运行一阵子不主动关掉的话,那个test文档可能几十M甚至更大了。。。可这是为什么呢? 后来上网查了下,有人说是“fput/get系列是有缓冲区的,而fseek(fp,0L,1)类似重新写入文件,也可以用fflush代替,效果一样。” 我开始怀疑这种说法,于是用fprintf函数来替代fputc,发现问题依旧存在,大家都知道,printf是有缓冲的输出,而fprintf是没有缓冲的。似乎上面的那个说法就不能成立。 还有一种说法是“对于一个可写可读流,是不能在一次读之后马上进行一次写,或者进行一次写之后马上进行一次读的,这可能会发生问题,需要在两个操作之间进行至少一次刷新,刷新的方法可以用fseek、rewind、fflush等等函数。” 总之,fseek函数除了有移动文件指针的动作外,还隐藏着一个_flush的动作。这个是肯定的。 很多高手都告诫说:fseek()定位文件指针只能用于二进制文件,文本文件要计算移动位数,易出差错。 最多说:fseek()只能用于二进制文件,不能用于文本文件,因为会引起字符翻译错误.如:输入'\n',将对应输出两个字符'\r''\n',而输入'\r'时会被忽略.结果就是引起输入和输出文件长度的不同。 |
|