C programming ungetc stdio.h


In C programming the <stdio.h> ungetc function pushes back the character that has been read,into the stream buffer.This function simply undo the effect of the ‘getc’ or ‘fgetc’ function call.After ‘unget’ has been called the character that is push back is the first character that will be read if ‘getc’ or ‘fgetc’ is call again provided any of the file positioning function (fseek ,fsetpos,or rewind) is not called in the intermediate.Calling ‘ungetc’ function does not change any external storage (for instance file) from which the character might have been read since the actual operation of pushing back happens in the stream buffer which is hidden from us.The declaration of the function is given below.

Link : C what are file stream and file buffer?

Link : C fseek stdio.h

int ungetc(int c, FILE *stream)

Parameters:
c -The character to push back to the stream.

stream -The stream form which the character to be pushed back is read.

Return type
int -Returns the character pushed back after conversion, or EOF if the operation fails.

A code example is given below and to understand the program consider a file name “text.txt” with the string “Happy programming!!!” exist in your current directory-the directory where your main.c file is present.In the program below after reading five characters we will call the ‘unget’ and try to read character from the same file again.

Code example

FILE *fp=fopen(“text.txt” , “r”);

int i=0 ,ret=0 ;

if(fp!=NULL)
{
while(i<5)
{
ret=getc(fp); //or fgetc(fp): either of the function works
printf(“%c” , ret); //print the character read from the ‘fp’ stream
}
}
else
 printf(“File opening failed!!!”);

ungetc(ret , fp ); //unget the 5th character read from the file

ret=getc( fp ); //read character from the stream ‘fp’ again

printf(“\n%c” , ret);

fclose(fp);

Output,

Happy
y

The character ‘y’ is pushed back to the stream buffer but calling the ‘getc’ reads the character ‘y’ again.

Another code example is given below same as the above program but in this case a file positioning function ‘rewind’ is called after calling ‘ungetc’ in the intermediate before calling the ‘getc’ again.

‘rewind’ set the file indicator position to the beginning of the stream or file.

Code example

FILE *fp=fopen(“text.txt” , “r”);

int i=0 ,ret=0 ;

if(fp!=NULL)
{
while(i<5)
{
ret=getc(fp); //or fgetc(fp): either of the function works
printf(“%c” , ret); //print the character read from the ‘fp’ stream
}
}
else
 printf(“File opening failed!!!”);

ungetc(ret , fp ); //unget the 5th character read from the file

rewind( fp ); //rewind the file position

ret=getc( fp ); //read character from the stream ‘fp’ again

printf(“\n%c” , ret);

fclose(fp);

Output,

Happy
H

Now you can see calling ‘getc’ after ‘rewind’ reads the first the character instead of the pushed back character.This happen since ‘rewind’ discards any pushed-back characters for the stream.





Some points to note about ‘ungetc’

i)If unget is called too many times

With ‘unget’ function one character push-back is guaranteed.However,if ‘ungetc’ is called too many times on the same stream without an intervening read or file positioning operation on that stream,the operation may fail.


ii)If the character being pushed-back is EOF

Suppose if the character passed as argument to ‘ungetc’ is an EOF character then the operation fails and the input stream remains unchanged.


iii)The state of file position indicator

To use ‘ungetc’ either a text file or binary file must be opened in a reading mode.If the file is a text file calling ‘ungetc’ leaves the file position indicator in an unspecified state until all the pushed-back character has been read again.For binary file the position indicator is decremented by each call to ‘ungetc’ if its value was zero before a call,it is indeterminate after the call.In either case after all the pushed-back character has been read the file indicator position is the same as before the first ‘ungetc’ call.


Related links

->C getc stdio.h

->C fgetc stdio.h

->C getchar stdio.h

->C fopen stdio.h

->C putc stdio.h