Reputation: 381
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
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 the
10`.
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
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