ungetc() — Push character onto input stream
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
ISO C |
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
/* 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
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);
}
}