Why the input "abc!!!" but the output is not "abc+++"?

208 Views Asked by At

I researching about input/output file.Below code relate some functions such as: fgetc(),fgets(),fputs(). i don't know why it does not work exactly as i want.Thank you so much ! Below is my code:

#include <stdio.h>
int main()
{
   FILE *fp; //FILE type pointer
   int c; //using to get each character from file
   char buffer [256]; //array as buffer to archive string

    fp = fopen("file.txt", "r"); /*open a file with only read mode*/
   if( fp == NULL ) 
    {
      perror("Error in opening file");
       return(-1);
    }
     while(!feof(fp)) /*check if has not yet reached to end of file*/
     {
       c = getc (fp); //get a character from fp          
       if( c == '!' )
      {
         ungetc ('+', fp); //replace '!' by '+'

      }
      else
      {
         ungetc(c, fp); //no change
      }
       fgets(buffer,255,fp);//push string of fp to buffer
       fputs(buffer, stdout); //outputting string from buffer to stdout
    }
    return(0);
 }

4

There are 4 best solutions below

2
mrAtari On

Maybe, because you're opening file read-only:

fp = fopen("file.txt", "r"); /*open a file with only read mode*/
3
monkeyStix On

The error happens, as pointed out by another answer, because you only test the first char in the file, and then read 255 bytes from it, instead of grabbing one byte at a time and testing it.

Also, an important thing to note is that ungetc only affects the stream and not the file:

Notice though, that this only affects further input operations on that stream, and not the content of the physical file associated with it, which is not modified by any calls to this function. (cplusplus.com)

Also, the function if only guaranteed for one consecutive use:

Pushed-back characters will be returned in reverse order; only one pushback is guaranteed. (linux manual)

3
Klas Lindbäck On

The logic in the while loop is flawed.

This is what happens:

You getc the first character, a.

a is not an ! so you ungetc a back on the stream.

Then you read an entire line. Of course you get abc!!!.

You then print the line. Output: abc!!!.

If you want to manipulate the string it is better to manipulate the buffer instead of trying to modify the stream:

   int i;
   int len = fgets(buffer,255,fp);//push string of fp to buffer
   for (i=0; i < len; i++) {
        if (buffer[i] == '!') {
             buffer[i] = '+';
        }
   }
   fputs(buffer, stdout); //outputting string from buffer to stdout

As an alternative, if you really want to use ungetc, you need to read/print one character at a time because ungetc can be done safely only on one character. Keep the if and the ungetc and replace the fgets/fputs with the following:

   fgets(buffer,1,fp);       // Read one character. 
   printf("%c", buffer[0]); // output one character from buffer to stdout
0
Efe Can On

You just control the first character of the file and control that if it's ! or not then you read 255 bytes from that stream and flush it to output stream.

For input file (which is abc!!! in your example) after reading 255 bytes from that file make feof() return True and break your loop because there is nothing to read.