Sachin Rana
Sachin Rana

Reputation: 381

fprintf is not printing to the file

In following code the fprintf is not printing to the file and printf is showing wrong output:

#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();
}

Upvotes: 1

Views: 6775

Answers (2)

Keith Thompson
Keith Thompson

Reputation: 263637

#include<stdio.h>

 void main()

This is wrong; it should be int main(void). If you have a book that tells you to use void main(), its author doesn't know C very well; 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.

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

Assuming everything went well so far, this will print 10 without a newline. If your program worked, its output would be 101000. Change "%d" to "%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.

    fseek(fp,t,SEEK_END);

Now you reposition the file pointer to 2 bytes before the end of the file. 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?)

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. 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. 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.

I also suggest that using names like d, w, and t make your code more difficult to read. 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.

With these changes, your current position in file.txt should now be just after the10`.

    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.

    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,

    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. If you insist on using it, you need, if I recall correctly, #include <windows.h>. You should turn up your compiler's warning levels if it didn't complain about a missing declaration for 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.

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. (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.)

Write your printf calls so the output is readable. Print newline (\n) at the end of each output lines.

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.

Upvotes: 1

sh1
sh1

Reputation: 4763

You need to perform an fseek() (or similar) between reads and writes in the same file. 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:

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.

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.

Upvotes: 0

Related Questions