Character I/O
Textbook Background
The C standard library gives specialized means to read characters and strings, explicitly, as described in the following textbook sections.
- King: Section 3.1, 23.5, pages 37-41, 612-615
Readings Characters
C provides two equivalent approaches for reading individual characters.
-
The C function
getchar()reads and returns a single character. For example:int ch; ch = getchar(); -
The
cformat forscanfreads an individual character. For example:char ch; scanf ("%c", &ch);
When reading character data with either getchar
or %c with scanf, the first character is read
and recorded; that is, the process of reading a character
does NOT skip over white space.
Some of you may have noticed that we declared an int
variable for reading using getchar. This is because
every binary value in the char type is mapped to some
sort of character encoding. However, when performing I/O, we need
extra codes to indicate the end of file or an error. Thus, the
value EOF fits in an int, but not
a char, and may be used to determine whether the end of
file been reached or an error has occurred, particularly when we are
reading input from a file stored on disk, rather than from the
terminal.
If valid data is read into ch, when a char is
expected, the compiler will often translate the int with a
simple cast for you.
Error Checking
The function scanf returns the number of variables
parsed OR the special value EOF when an error or
end-of-file (no input) is encountered. Thus, error checking
with scanf usually involves testing for the specific
return value expected (i.e., two items).
Similarly, getchar returns either the character read
or EOF. Thus, error checking for a call
to getchar is slightly different than
for scanf, and might proceed something like the following:
int ch;
ch = getchar();
if (ch == EOF) {
/* Handle reading error or end-of-input appropriately (i.e., print
error message, exit program, etc.) */
}
Reading Strings
C also provides at least three approaches for reading strings of characters. Each function has its own special characteristics.
-
The
sformat forscanfreads a sequence of non-white-space characters. As with all strings, a null character ('\0') is added at the end of the string. For example:char str[10]; /* allow room for 10 characters, including the null */ scanf ("%9s", str); /* since str is an array, the variable represents a base address and no ampersand & is added */ -
The C function
gets()reads an entire line or until end of file. As withscanf, a null character is added at the end of the string. For example:char str[10]; gets (str); -
The C function
fgets()reads up toncharacters from a line or until a newline character is found or the "end of file". As withscanf, a null character is added at the end of the string. Unlikescanf, the newline character might be included in the string (so long as doing so wouldn't exceed the character limit). For example:
The needed length of a string may change; using the same constant value throughout the code (as above) is dangerously poor practice. A better way to proceed in cases like this is to declare a constant to hold the desired length. For example:char str[10]; /* stdin is the C variable for "standard input" */ fgets (str, 10, stdin); /* up to 9 characters are read from the terminal (possibly including the newline), leaving room for a null character at the end */#define BUFFER_SIZE 10 char str[BUFFER_SIZE]; /* stdin is the C variable for "standard input" */ fgets (str, BUFFER_SIZE, stdin); /* up to bufsz-1 characters are read from the terminal (possibly including the newline), leaving room for a null char at the end */
As with reading character data, stored input starts immediately with the first character read; the process of reading a string does NOT skip over white space.
Warning: Both scanf with the simple
"%s" format and gets read
characters (until white space or the end of a line, respectively),
without regard for the size of the string array. If more characters
are read than fit in the array, the characters may overflow memory to
fill data stored in other variables. Thus, only fgets,
getchar, and scanf with the "%Ns" format can be considered safe.
Error Checking
Whereas scanf returns the number of variables
parsed, fgets returns
a char* pointer that
is NULL if there was an error or end
of file. Thus, error checking for a call to fgets is
slightly different than for scanf, and might proceed
something like the following:
char * readVal;
readVal = fgets(...);
if (readVal == NULL) {
/* Handle reading error or end-of-input appropriately (i.e., print
error message, exit program, etc.) */
}
