Node:getc and fgetc, Next:putc and fputc, Previous:putchar, Up:Single-character input and output
getc
and fgetc
If you want to read a single character from a stream other than
stdin
, you can use the getc
function. This function is
very similar to getchar
, but accepts an argument that specifies
the stream from which to read. It reads the next character from the
specified stream as an unsigned char
, and returns its value,
converted to an integer. If a read error occurs or the end of the file
is reached, getc
returns EOF
instead.
Here is a code example that makes use of getc
. This code example
creates a text file called snazzyjazz.txt
with fopen
,
writes the alphabet in upper-case letters plus a newline to it with
fprintf
, reads the file position with ftell
, and gets the
character there with getc
. It then seeks position 25 with
fseek
and repeats the process, attempts to read past the end of
the file and reports end-of-file status with feof
, and generates
an error by attempting to write to a read-only stream. It then reports
the error status with ferror
, returns to the start of the file
with rewind
and prints the first character, and finally attempts
to close the file and prints a status message indicating whether it
could do so.
See File position, for information on ftell
, fseek
, and
rewind
. See End-of-file and error functions, for more
information on feof
and ferror
.
#include <stdio.h> int main() { int input_char; FILE *my_stream; char my_filename[] = "snazzyjazz.txt"; long position; int eof_status, error_status, close_error; my_stream = fopen (my_filename, "w"); fprintf (my_stream, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); /* Close stream; skip error-checking for brevity of example */ fclose (my_stream); printf ("Opening file...\n"); my_stream = fopen (my_filename, "r"); position = ftell (my_stream); input_char = getc (my_stream); printf ("Character at position %d = '%c'.\n\n", position, input_char); printf ("Seeking position 25...\n"); fseek (my_stream, 25, SEEK_SET); position = ftell (my_stream); input_char = getc (my_stream); printf ("Character at position %d = '%c'.\n\n", position, input_char); printf ("Attempting to read again...\n"); input_char = getc (my_stream); eof_status = feof (my_stream); printf ("feof returns %d.\n\n", eof_status); error_status = ferror (my_stream); printf ("ferror returns %d.\n", error_status); printf ("Attempting to write to this read-only stream...\n"); putc ('!', my_stream); error_status = ferror (my_stream); printf ("ferror returns %d.\n\n", error_status); printf ("Rewinding...\n"); rewind (my_stream); position = ftell (my_stream); input_char = getc (my_stream); printf ("Character at position %d = '%c'.\n", position, input_char); close_error = fclose (my_stream); /* Handle fclose errors */ if (close_error != 0) { printf ("File could not be closed.\n"); } else { printf ("File closed.\n"); } return 0; }
There is another function in the GNU C Library called fgetc
. It
is identical to getc
in most respects, except that getc
is
usually implemented as a macro function and is highly optimised, so is
preferable in most situations. (In situations where you are reading
from standard input, getc
is about as fast as fgetc
, since
humans type slowly compared to how fast computers can read their input,
but when you are reading from a stream that is not interactively
produced by a human, fgetc
is probably better.)