在下面的代码中,fprintf没有打印到文件,printf显示错误的输出:
#include<stdio.h>
void main()
{
FILE *fp;
int d,w,t;
fp = fopen("file.txt","r+");//already created file having value 10
fscanf(fp,"%d",&d);
printf("%d",d);//print value 10
t=ftell(fp);
fseek(fp,t,SEEK_END);
fprintf(fp,"%d",1000); // printing 1000 to the file
fscanf(fp,"%d",&w);
printf("%d",w); // this printf is still printing wrong value 12803
fclose(fp);
getch();
}
答案 0 :(得分:1)
#include<stdio.h>
void main()
这是错的;它应该是int main(void)
。如果你有一本书
告诉你使用void main()
,它的作者不太了解C;
得到一本更好的书。
{
FILE *fp;
int d,w,t;
fp = fopen("file.txt","r+");//already created file having value 10
您需要检查fopen
呼叫是否成功,以及
如果程序失败,可能会终止程序。
fscanf(fp,"%d",&d);
printf("%d",d);//print value 10
假设到目前为止一切顺利,这将打印10
而不使用换行符。
如果您的程序有效,其输出将为101000
。将“%d”更改为“%d \ n”。
t=ftell(fp);
t
是文件中的当前位置,应该在之后
10
,所以从一开始就是2个字节。
fseek(fp,t,SEEK_END);
现在,在结束之前将文件指针重新定位到2个字节
文件。这没有任何意义。你最终亲戚的地方
到“10”取决于file.txt
中的其他内容(换行符?CR-LF?)
您可以保存ftell()
返回的值,稍后再使用它
调用fseek
,但只有第三个参数才有意义
SEEK_SET
。所以你可能想要:
t = ftell(fp);
fseek(fp, t, SEEK_SET);
这不会改变你在文件中的位置,但它确实允许你 从你写过的文件中读取。
哦,ftell
和fseek
使用long
值,而不是int
。
如果文件不是,您的程序(带有这些修复程序)可能会起作用
太大了,但你真的应该将t
声明为long
变量。
我还建议使用d
,w
和t
等名称使您的代码更难以阅读。使用更长的描述性名称。考虑一下除了您尝试阅读和理解您的代码之外的其他人 - 或者您从现在起一个月内读取自己的代码,当您忘记了d
时。
通过这些更改,您当前在file.txt should now be
just after the
10`中的位置。
fprintf(fp,"%d",1000); // printing 1000 to the file
现在您在1000
之后立即打印10
,现在是文件
包含101000
,您的当前位置在之后
你写的人物。
fscanf(fp,"%d",&w);
在这里,您尝试在写入后立即从文件中读取。
但是你在文件的末尾,所以没有什么可读的。
因为你没有检查fscanf
的结果(这会告诉你
它失败了),w
没有改变,
printf("%d",w); // this printf is still printing wrong value 12803
同样,添加换行符会使输出更容易阅读。
fclose(fp);
getch();
getch()
是Windows特定的(和MSDOS特定的)功能
在终止程序之前等待用户输入。如果你坚持
在使用它时,如果我没记错的话,你需要#include <windows.h>
。
如果没有抱怨,你应该调高编译器的警告级别
关于getch
的遗失声明。
}
要点:
如果要读取和写入同一个打开的文件,可以这样做
- 但你需要调用一些定位功能,例如fseek
在阅读和写作之间,或在写作和阅读之间。
您应该检查所有库调用返回的值。对于
例如,如果file.txt
不存在,您的程序会悄然忽略
错误并继续尝试读取和写入文件,用
未定义的结果。 (忽略printf
的结果是很常见的
打电话,因为如果打印到标准,你可以做很多事情
输出失败,但无论如何都要看结果是有益的。)
编写printf
个调用,以便输出可读。打印换行符
(\n
)在每个输出行的末尾。
阅读您使用的每项功能的文档。
让你的编译器警告你有问题的结构。看你的 编译器的文档,以了解如何执行此操作。
答案 1 :(得分:0)
您需要在同一文件中执行读取和写入之间的fseek()
(或类似)。这并不是所有实现中的严格要求,但它对于可移植性是必要的。
修改强>
好的,你的新版本有:
t=ftell(fp);
fseek(fp,t,SEEK_END);
在某些情况下可能有意义,但可能不是这个。一世 认为你的意思是:
fseek(fp, 0, SEEK_CUR);
相对于当前位置寻找,而不实际移动 任何地方。
但是你没有得到w==1000
的原因是在这两行之间:
fprintf(fp,"%d",1000); // printing 1000 to the file
fscanf(fp,"%d",&w);
你在这里没有寻求从写作过渡到阅读。你不能
完全确定文件中的哪个位置会尝试阅读w
从没有寻求重新确定你想要的位置。
尝试:
t = ftell(fp);
fprintf(fp,"%d",1000); // printing 1000 to the file
fseek(fp, t, SEEK_SET);
fscanf(fp,"%d",&w);
顺便提一下,这个代码还有很多其他的危险;喜欢
fprintf
不打印任何终止字符,所以那里
你写完之后可能是跟踪数字(从之前的
写入附加到值的其他值或其他值
阅读w
。