-3

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 Answers4

2

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
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • thank you so much ! but i want to use ungetc() function. Do you have a other way that still use ungetc() function ? – Thuan Tran Jul 25 '16 at 08:32
  • @ThuanTran As monkeyStix points out, you can only `ungetc` one character safely. So you need to read and print one character at a time if you want to use `ungetc`. Se added alternative in my answer. – Klas Lindbäck Jul 25 '16 at 08:44
  • 1
    thank ! i replaced fgets(buffer,2,fp); and fputs(buffer, stdout); to printf("%c",fgetc(fp)); and result is true – Thuan Tran Jul 25 '16 at 09:00
0

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)

monkeyStix
  • 620
  • 5
  • 10
  • Thank you so much ! i know that file no change, only stream just change. But why do my code run not true ? and are there problem when i use ungetc() ? – Thuan Tran Jul 25 '16 at 08:41
  • can you rewrite my code but still use ungetc() function ? thank. – Thuan Tran Jul 25 '16 at 08:45
  • thank ! i replaced fgets(buffer,2,fp); and fputs(buffer, stdout); to printf("%c",fgetc(fp)); and result is true – Thuan Tran Jul 25 '16 at 09:02
0

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.

Efe Can
  • 1
  • 1
-1

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

fp = fopen("file.txt", "r"); /*open a file with only read mode*/
mrAtari
  • 620
  • 5
  • 17