ungetc() — Push character onto input stream

Standards

Standards / Extensions C or C++ Dependencies

ISO C
POSIX.1
XPG4
XPG4.2
C99
Single UNIX Specification, Version 3
Language Environment

both  

Format

#include <stdio.h>

int ungetc(int c, FILE *stream);

#define _OPEN_SYS_UNLOCKED_EXT 1
#include <stdio.h>

int ungetc_unlocked(int c, FILE *stream);

General description

Pushes the character specified by the value of c converted to the unsigned char back onto the given input stream. The pushed-back characters are returned by any subsequent read on the same stream in the reverse order of their pushing. That is, the last character pushed will be returned first.

Up to 4 characters can be pushed back to a given input stream. You can call ungetc() up to 4 times consecutively; this will result in 4 characters being pushed back in total.

The stream must be open for reading. A subsequent read operation on the stream starts with c. You cannot push EOF back on the stream using ungetc(). A successful call to the ungetc() function clears the EOF indicator for the stream.

Characters pushed back by ungetc(), and subsequently not read in, will be erased if a fseek(), fsetpos(), rewind(), or fflush() function is called before the character is read from the stream. After all the pushed-back characters are read in, the file position indicator is the same as it was before the characters were pushed back.

Each character of pushback backs up the file position by one byte. This affects the value returned by ftell() or fgetpos(), the result of an fseek() using SEEK_CUR, or the result of an fflush(). For example, consider a file that contains: a b c d e f g h

After you have just read 'a', the current file position is at the start of 'b'. The following operations will all result in the file position being at the start of 'a', ready to read 'a' again.
/* 1 */       ungetc('a', fp);
              fflush(fp);  /* flushes ungetc char and keeps position */

/* 2 */       ungetc('a', fp);
              pos = ftell(fp); /* points to first character */
              fseek(fp, pos, SEEK_SET);

/* 3 */       ungetc('a',fp);
              fseek(fp, 0, SEEK_CUR) /* starts at new file pos'n */

/* 4 */       ungetc('a', fp);
              fgetpos(fp, &fpos); /* gets position of first char */
              fsetpos(fp, &fpos);

You can use the environment variable _EDC_COMPAT to cause a z/OS® XL C/C++ application to ignore ungetc() characters for fflush(), fgetpos(), and fseek() using SEEK_CUR. For more details, see z/OS XL C/C++ Programming Guide.

The ungetc() function is not supported for files opened with type=record or type=blocked.

ungetc() has the same restriction as any read operation for a read immediately following a write or a write immediately following a read. Between a write and a subsequent read, there must be an intervening flush or reposition. Between a read and a subsequent write, there must also be an intervening flush or reposition unless an EOF has been reached.

ungetc_unlocked() is functionally equivalent to ungetc() with the exception that it is not thread-safe. This function can safely be used in a multithreaded application if and only if it is called while the invoking thread owns the (FILE*) object, as is the case after a successful call to either the flockfile() or ftrylockfile() function.

Returned value

If successful, ungetc() returns the integer argument c converted to an unsigned char

If c cannot be pushed back, ungetc() returns EOF.

ungetc() is treated as a read operation. A flush or reposition is required after a call to ungetc() and before the next write operation.

Example

CELEBU04
⁄* CELEBU04                                      

   In this example, the while statement reads decimal digits                    
   from an input data stream by using arithmetic statements to                  
   compose the numeric values of the numbers as it reads them.                  
   When a nondigit character appears before the EOF, &ungetc.                   
   replaces it in the input stream so that later input functions                
   can process it.                                                              
                                                                                
 *⁄                                                                             
#include <stdio.h>                                                              
#include <ctype.h>                                                              
                                                                                
int main(void)                                                                  
{                                                                               
   FILE *stream;                                                                
   int ch;                                                                      
   unsigned int result = 0;                                                     
                                                                                
   stream = fopen("myfile.dat","r+");                                           
   while ((ch = getc(stream)) != EOF && isdigit(ch))                            
   {                                                                            
      result = result * 10 + ch - '0';                                          
   }                                                                            
   printf("result is %i\n",result);                                             
   if (ch != EOF)                                                               
   {                                                                            
      ungetc(ch,stream);         ⁄* Put the nondigit character back *⁄          
      ch=getc(stream);                                                          
      printf("value put back was %c\n",ch);                                     
   }                                                                            
}                                                                               

Related information