fprintf,fseek共同读写文件时的真实情况,请各位C朋友点评 <很蹊跷>

nishizuihaode 2009-06-03 11:00:50
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;
int main()
{
FILE * fp;
char *buffer = new char[100];
char ch;
fp = fopen("c:\\abc.txt","a+");
if (fp == NULL)
cout <<"Open FILE ERROR";
else
cout <<"Open FILE SUCCESSFUL" <<endl;

while(!feof(fp))
{
ch=fgetc(fp);
if(ch!=EOF)
{
cout << ch;
fgets(buffer,100,fp);
cout <<buffer;
long pos = ftell(fp);
cout<<pos<<endl;
if (strstr(buffer,"you"))
{
fseek(fp,0,SEEK_END);
fprintf(fp,"%s\n","888888");
cout<<ftell(fp)<<endl;
//break;
cout <<buffer;
}
cout <<"wait..." <<endl;
//fseek(fp,pos,SEEK_SET); 如将此处注释回复,程序运行正常
continue;

}
}
fclose(fp);
delete buffer;
buffer = NULL;
return 0;
}

程序目的:读取文件,当文件内容含有“you”时在文件末尾添加字符串“8888888”,当读取文件结束后退出
实验发现:当程序没有指定//fseek(fp,pos,SEEK_SET)时文件一直再写入文件,并且写入的内容很蹊跷
文件abc.txt
222222333estsdfsdfsdyou are bestyou

利用本程序则写入后的文件为:
222222333estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
......

...全文
307 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
chary8088 2009-06-04
  • 打赏
  • 举报
回复
我上面给你修改的代码就是这样的,你自己仔细想想吧
nishizuihaode 2009-06-04
  • 打赏
  • 举报
回复
我是这样想的,还请各位指正啊
经过fprintf(fp,"%s\n","888888");后的文件指针已经到了文件的尾了,再一次回到while循环后,经过对文件指针的判断后向下执行,当执行到
ch=fgetc(fp);
if(ch!=EOF)
时,应该判断出文件的标志符EOF,从而对出循环体了
能不能就这个过程详细帮我理顺下,谢谢
chary8088 2009-06-04
  • 打赏
  • 举报
回复
#include <iostream> 
#include <stdio.h>
#include <string.h>

using namespace std;
int main()
{
FILE * fp;
char *buffer = new char[100];
char ch;
fp = fopen("c:\\abc.txt","a+");
if (fp == NULL)
cout < <"Open FILE ERROR";
else
cout < <"Open FILE SUCCESSFUL" < <endl;

while(!feof(fp))
{
ch=fgetc(fp);
if(ch!=EOF)
{
cout < < ch;
fgets(buffer,100,fp);
cout < <buffer;
long pos = ftell(fp);
cout < <pos < <endl;
if (strstr(buffer,"you"))
{
fseek(fp,0,SEEK_END);
fprintf(fp,"%s\n","888888");
cout < <ftell(fp) < <endl;
//break;
cout < <buffer;
}
cout < <"wait..." < <endl;
//fseek(fp,pos,SEEK_SET); 如将此处注释回复,程序运行正常 --------------注意pos
continue;

}
}
fclose(fp);
delete buffer;
buffer = NULL;
return 0;
}

程序目的:读取文件,当文件内容含有“you”时在文件末尾添加字符串“8888888”,当读取文件结束后退出
实验发现:当程序没有指定//fseek(fp,pos,SEEK_SET)时文件一直再写入文件,并且写入的内容很蹊跷
文件abc.txt
222222333estsdfsdfsdyou are bestyou

利用本程序则写入后的文件为:
222222333estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
888888
33estsdfsdfsdyou are bestyou
......


谢谢各位
但有一点不太明白
通过fprintf(fp,"%s\n","888888");后的文件指针已经到了文件的最后了,为啥还要fseek(fp,ftell(fp),SEEK_SET)呢?

指针是移到文件最后了,但是你的
//fseek(fp,pos,SEEK_SET); 如将此处注释回复,程序运行正常 --------------注意pos
还是以前的位置!!!!!!!!!!!!!!!
w0911h 2009-06-03
  • 打赏
  • 举报
回复
fprintf()之后数据不是立即写入文件,但是文件指针却已经算到你写入888888之后了,但是实际文件中只到bestyou就结束了,问题可能出在这里,具体为什么我也不是很清楚,等待高手,你可以试着在fprintf()之后加上fflush(fp)看看
nishizuihaode 2009-06-03
  • 打赏
  • 举报
回复
不好意思哦,有个错别字
//fseek(fp,pos,SEEK_SET); 如将此处注释恢复,程序运行正常

请各位路过的朋友不吝赐教
mymtom 2009-06-03
  • 打赏
  • 举报
回复
在fgets(buffer,100,fp); 后加fflush
因按读写方式打开文件后,不能读后马上写,反之亦然,需要加fflush/fseek, fsetpos 或 rewind.
按ISO C99的说法:
6 When a file is opened with update mode ('+' as the second or third character in the
above list of mode argument values), both input and output may be performed on the
associated stream. However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by output without an
intervening call to a file positioning function, unless the input operation encounters endof-
file. Opening (or creating) a text file with update mode may instead open (or create) a
binary stream in some implementations.
nishizuihaode 2009-06-03
  • 打赏
  • 举报
回复
谢谢各位
但有一点不太明白
通过fprintf(fp,"%s\n","888888");后的文件指针已经到了文件的最后了,为啥还要fseek(fp,ftell(fp),SEEK_SET)呢?
chary8088 2009-06-03
  • 打赏
  • 举报
回复
    FILE * fp; 
char *buffer = new char[100];
char ch;
fp = fopen("abc.txt","a+");
if (fp == NULL)
cout <<"Open FILE ERROR";
else
cout <<"Open FILE SUCCESSFUL" <<endl;

while(!feof(fp))
{
ch=fgetc(fp);
if(ch!=EOF)
{
cout << ch;
fgets(buffer,100,fp);
cout <<buffer;
long pos = ftell(fp);
cout <<pos <<endl;
if (strstr(buffer,"you"))
{
fseek(fp,0,SEEK_END);
fprintf(fp,"%s\n","888888");
cout <<ftell(fp) <<endl;
//break;
cout <<buffer;
}
cout <<"wait..." <<endl;
pos = ftell(fp); //指针位置要及时更新!!!
fseek(fp,pos,SEEK_SET);// 如将此处注释回复,程序运行正常
continue;

}
}

fclose(fp);
delete buffer;
buffer = NULL;
return 0;
chary8088 2009-06-03
  • 打赏
  • 举报
回复
这样就可以了
很简单的
    FILE * fp; 
char *buffer = new char[100];
char ch;
fp = fopen("abc.txt","a+");
if (fp == NULL)
cout <<"Open FILE ERROR";
else
cout <<"Open FILE SUCCESSFUL" <<endl;

while(!feof(fp))
{
ch=fgetc(fp);
if(ch!=EOF)
{
cout << ch;
fgets(buffer,100,fp);
cout <<buffer;
long pos = ftell(fp);
cout <<pos <<endl;
if (strstr(buffer,"you"))
{
fseek(fp,0,SEEK_END);
fprintf(fp,"%s\n","888888");
cout <<ftell(fp) <<endl;
//break;
cout <<buffer;
}
cout <<"wait..." <<endl;
pos = ftell(fp);
fseek(fp,pos,SEEK_SET);// 如将此处注释回复,程序运行正常
continue;

}
}

fclose(fp);
delete buffer;
buffer = NULL;
return 0;
  • 打赏
  • 举报
回复
fseek(fp,pos,SEEK_SET)
加进去之后还有问题?

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧