简体   繁体   English

fprintf没有打印到文件

[英]fprintf is not printing to the file

In following code the fprintf is not printing to the file and printf is showing wrong output: 在以下代码中,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();
}
#include<stdio.h>

 void main()

This is wrong; 这是错误的; it should be int main(void) . 它应该是int main(void) If you have a book that tells you to use void main() , its author doesn't know C very well; 如果您有一本书告诉您使用void main() ,那么它的作者不太了解C。 get a better book. 得到一本更好的书。

{
    FILE *fp;
    int d,w,t;
    fp = fopen("file.txt","r+");//already created file having value 10

You need to check whether the fopen call succeeded or not, and probably terminate the program if it failed. 您需要检查fopen调用是否成功,并且如果失败则可能终止程序。

    fscanf(fp,"%d",&d);
    printf("%d",d);//print value 10

Assuming everything went well so far, this will print 10 without a newline . 假设到目前为止一切顺利,这将在不使用换行符的情况下输出10 If your program worked, its output would be 101000 . 如果您的程序有效,则其输出将为101000 Change "%d" to "%d\\n". 将“%d”更改为“%d \\ n”。

    t=ftell(fp);

t is the current position in the file, which should be just after the 10 , so it's 2 bytes from the beginning. t是文件中的当前位置,应该在10后面,因此它是从开始起2个字节。

    fseek(fp,t,SEEK_END);

Now you reposition the file pointer to 2 bytes before the end of the file . 现在,您将文件指针重新定位到文件末尾之前的 2个字节。 That doesn't make any sense. 那没有任何意义。 Where you end up relative to the "10" depends on what else is in file.txt (newline? CR-LF?) 相对于“ 10”的最终位置取决于file.txt其他内容(换行符?CR-LF?)

You can save the value returned by ftell() and use it later in a call to fseek , but that only makes sense if the third argument is SEEK_SET . 您可以保存ftell()返回的值,并稍后在调用fseek使用它,但这仅在第三个参数为SEEK_SET So you probably want: 因此,您可能想要:

t = ftell(fp);
fseek(fp, t, SEEK_SET);

That doesn't change your position in the file, but it does allow you to read from a file that you've been writing to. 那不会改变您在文件中的位置,但是它允许您从一直在写入的文件中读取内容。

Oh, and ftell and fseek work with long values, not int . 哦, ftellfseek具有long值,而不是int Your program (with these fixes) is likely to work if the file isn't too big, but you really should declare t as long variable. 如果文件不是太大,则程序(带有这些修复程序)可能会运行,但是您实际上应该将t声明为long变量。

I also suggest that using names like d , w , and t make your code more difficult to read. 我还建议使用诸如dwt使您的代码更难以阅读。 Use longer descriptive names. 使用更长的描述性名称。 Think about someone other than you trying to read and understand your code -- or you reading your own code a month from now, when you've forgotten what d is. 除了尝试阅读和理解您的代码之外,请考虑其他人-或者您从现在开始每个月都在忘记d情况下阅读自己的代码。

With these changes, your current position in file.txt should now be just after the 10`. 进行了这些更改后,您在file.txt should now be just after the的当前位置file.txt should now be just after the

    fprintf(fp,"%d",1000); // printing 1000 to the file

And now you print 1000 immediately after the 10 , so now the file contains 101000 , and your current position is after the last character you wrote. 现在,您在10之后立即打印1000 ,因此文件包含101000 ,并且当前位置您写入的最后一个字符之后

    fscanf(fp,"%d",&w);

Here you try to read from the file immediately after writng to it. 在这里,您尝试在写入文件后立即读取文件。 But you're at the end of the file, so there's nothing to read. 但是,您位于文件的结尾,因此没有什么可读取的。 Since you didn't check the result of fscanf (which would have told you it failed), w is unchanged, 由于您没有检查fscanf的结果(这会告诉您它失败了),因此w不变,

    printf("%d",w); // this printf is still printing wrong value 12803

Again, adding a newline would make the output much easier to read. 同样,添加换行符会使输出更易于阅读。

    fclose(fp);
    getch();

getch() is a Windows-specific (and MSDOS-specific) function that waits for user input before terminating your program. getch()是Windows特定(和MSDOS特定)的函数,在终止程序之前等待用户输入。 If you insist on using it, you need, if I recall correctly, #include <windows.h> . 如果您坚持使用它,并且我没记错的话,您需要#include <windows.h> You should turn up your compiler's warning levels if it didn't complain about a missing declaration for getch . 如果编译器没有抱怨getch缺少声明,则应提高编译器的警告级别。

}

Summary: 摘要:

If you want to read and write to the same open file, you can do that -- but you need to call some positioning function such as fseek between reading and writing, or between writing and reading. 如果要读取和写入相同的打开文件,则可以执行此操作-但需要在读取和写入之间或在写入和读取之间调用某些定位功能,例如fseek

You should check the values returned by all library calls. 您应该检查所有库调用返回的值。 For example, if file.txt doesn't exist, your program quietly ignores the error and continues to try to read and write to the file, with undefined results. 例如,如果file.txt不存在,则您的程序会悄悄地忽略该错误,并继续尝试读取和写入文件,结果未定义。 (It's common to ignore the result of a printf call, since there's not a lot you can do if printing to standard output fails, but it's instructive to look at the result anyway.) (通常会忽略printf调用的结果,因为如果打印到标准输出失败,您将无能为力,但是无论如何看一下结果都是有启发性的。)

Write your printf calls so the output is readable. 编写printf调用,使输出可读。 Print newline ( \\n ) at the end of each output lines. 在每行输出的末尾打印换行符( \\n )。

Read the documentation for each function you use. 阅读您使用的每个功能的文档。

Ask your compiler to warn you about questionable constructs. 请您的编译器警告您有关可疑构造的信息。 See your compiler's documentation to find out how to do this. 请参阅编译器的文档,以了解如何执行此操作。

You need to perform an fseek() (or similar) between reads and writes in the same file. 您需要在同一文件的读取和写入之间执行fseek() (或类似操作)。 It's not a strict requirement in all implementations, but it's necessary for portability. 这不是所有实现中的严格要求,但对于可移植性是必需的。


EDIT 编辑

OK, your new verison has: 好的,您的新版本具有:

t=ftell(fp);
fseek(fp,t,SEEK_END);

which might make sense in some instances, but probably not this one. 在某些情况下这可能很有意义,但可能并非如此。 I think you meant: 我想你的意思是:

fseek(fp, 0, SEEK_CUR);

which seeks relative to the current position, without actually moving anywhere. 相对于当前位置进行搜索,而不实际移动到任何位置。

But the reason you're not getting w==1000 is between these two lines: 但是没有得到w==1000的原因是在这两行之间:

fprintf(fp,"%d",1000); // printing 1000 to the file
fscanf(fp,"%d",&w);

You transition from writing to reading without a seek here. 您可以从写作过渡到阅读,而无需在这里寻求帮助。 You can't be altogether sure where in the file you're going to try to read w from without using a seek to re-assert the position you intend. 您无法完全确定要尝试从中读取w的文件中的哪个位置,而无需使用寻求重新确定您想要的位置的尝试。

Try: 尝试:

t = ftell(fp);
fprintf(fp,"%d",1000); // printing 1000 to the file
fseek(fp, t, SEEK_SET);
fscanf(fp,"%d",&w);

There are a bunch of other hazards around this code, by the way; 顺便说一句,此代码周围还有很多其他危害。 like that the fprintf doesn't print any terminating character, so there might be trailing digits after where you've written (from previous writes of other values, or whatever) which get appended to the value read into w . 就像fprintf不会打印任何终止符一样,因此在您写入的位置(之前写入的其他值,或其他值)之后可能会有尾随的数字,这些数字将附加到读入w的值之后。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM