1

I have a file named datafile.txt which contains

Line 1 here
Line 2 here

I want to store the first line in a character array and then replace the first charecter of the second line by 't' so I wrote the following code for this:

#include <stdio.h>
int main(){ 
    FILE *fp=fopen("datafile.txt","r+");
    char line[100];
    fgets(line,100,fp);
    printf("The position of file pointer is %d",ftell(fp));
    fprintf(fp,"t");
    fclose(fp); 
}

The output is

The position of file pointer is 13

The problem here is that the fprintf is not working in this case i.e. I have tested the return value of fprintf which comes out to be 1 which means that fprintf is working but when I open the datafile.txt file then I can see that the first character of second line has not been replaced by 't' .If I add a fseek statement like this then it works:

#include <stdio.h>
int main(){ 
    FILE *fp=fopen("datafile.txt","r+");
    char line[100];
    fgets(line,100,fp);
    fseek(fp,ftell(fp),SEEK_SET);
    printf("The position of file pointer is %d",ftell(fp));
    fprintf(fp,"t");
    fclose(fp); 
}

The output on screen is the same as in the last case but in this case the first character of line 2 is replaced by 't'.

Can someone please explain me why this is not working in the first case but after adding the fseek statement it works. The position of file pointer is same in both the cases then too in first case it is not working.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I can't replicate your problem, the first program works well for me. Is it really a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) of the *failing* program? Do your actual program do something which you forgot to tell us? Are you perhaps checking the file *before* the buffers are flushed (and actually written)? What happens if you add an explicit `fflush(fp)` after the `fprintf`? – Some programmer dude Aug 20 '17 at 06:34
  • `fprintf(fp,"t");` should be `fprintf(fp,"%s","t");` – haccks Aug 20 '17 at 06:39
  • @Someprogrammerdude Try the program in Dev C++.Which IDE are you using right now? – Chaitanya Vaishampayan Aug 20 '17 at 06:49
  • The IDE used should not matter. As for why it works with `fseek` it's probably because it causes an implicit flush (i.e. it calls `fflush`). – Some programmer dude Aug 20 '17 at 07:04
  • @Someprogrammerdude if I use fflush(fp) instead of fseek, the output changes to "The position of file pointer is 26" and the file remains unchanged. And if I use fflush after fprintf then too no change actually occurs in the file. – Chaitanya Vaishampayan Aug 20 '17 at 07:25
  • 4
    One plausible source of trouble is that you must do a positioning operation between a read and a write operation on an file open for update. Even if that is `fseek(fp, 0L, SEEK_CURRENT)`, you should do it. That may or may not be the cause of your trouble, but the standard officially requires it. – Jonathan Leffler Aug 20 '17 at 07:44
  • 1
    @haccks: Why? `"t"` is a string literal with no format specifiers and therefore no risk of misinterpretation. The advice is sound for `fprintf(f, str)`, which should be `fprintf(f, "%s", str)`, but I think you are taking your safety concerns a bit too far here. – M Oehm Aug 20 '17 at 08:28
  • Which platform are you working on — O/S and compiler? – Jonathan Leffler Aug 20 '17 at 16:46
  • 1
    Since the `fseek()` fixes the problem, I've closed this as a duplicate of a question which has answers about why the the `fseek()` is required. Ultimately, it is because the standard says that an `fseek()` or similar operation is required. The current duplicate ([Why `fseek()` or `fflush()` is always required between reading and writing in update modes?](https://stackoverflow.com/questions/1713819/) has a quote from the standard which requires that behaviour. – Jonathan Leffler Aug 20 '17 at 17:16

0 Answers0