When opening a file in "r+"
update mode, you open the file for both reading and writing.
However, this does not mean that you can freely switch between reading and writing. According to §7.21.5.3 ¶7 of the ISO C11 standard, there are certain restrictions:
- Output cannot be followed by input without an intervening call to
fflush
or to a file positioning function (fseek
, fsetpos
or rewind
).
- Input cannot be followed by output without an intervening call to a file positioning function, unless the input operation encountered end-of-file.
In your posted code, you are violating both rules, which has the consequence that your program is invoking undefined behavior. This means that anything may happen, including the possibility that your I/O functions are reading or writing nonsense.
Also, your program has another bug. The line
while(!feof(o)){
does not make sense. See the following question for the reason why:
Why is “while ( !feof (file) )” always wrong?
Also, you should always close the file with fclose
, otherwise, depending on your platform, it is possible that the output buffer will not be flushed.
Here is a program which fixes all the bugs described above:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
//attempt to open file
fp = fopen( "o.txt", "r+" );
if ( fp == NULL )
{
fprintf( stderr, "error opening file!\n" );
exit( EXIT_FAILURE );
}
for (;;) //infinite loop, equivalent to while(1)
{
long prev_pos;
int c;
//remember previous file position, so that we can jump
//back to it for writing, if necessary
prev_pos = ftell( fp );
//attempt to read next character
c = fgetc( fp );
//break infinite loop if end-of-file (or error) encountered
if ( c == EOF )
break;
//replace character, if appropriate
if ( c == 'h' )
{
//jump back to previous position
fseek( fp, prev_pos, SEEK_SET );
//write replacement character
fputc( '#', fp );
//flush the stream
fflush( fp );
}
}
//close the file
fclose( fp );
return 0;
}