Another improvement we can make to the guessing game program is to make the player interface more natural. When we ask the player if they want to continue, they must enter 0 or 1 to answer. It might be better to allow them to enter y or n.
But 'y' and 'n' are not integers - they are characters entered from the keyboard. How do we store characters?
The char data type
C provides another primitive data type called char, and we can declare variabels of this type:
char ch;
This declaration allocates a cell that can hold exactly one character:
We can assign characters to this cell using character constants:
ch = 'y';
We can also read a single character from the input by using the %c conversion specifier in the format string given to scanf():
scanf("%c", &ch);
We could then compare the character read:
if( ch == 'y' ) keep_playing = TRUE;
else keep_playing = FALSE;
The modified code is in guess.c improved.
Look at a new program count.c. This is a short program to count the number of characters in a file. You can test it out with the input file count.dat.
Character I/O
We have seen how we can declare character variables:
char ch;
how we can assign constant values to such a variable:
ch = 'r';
and how to read and print character variables:
scanf("%c",&ch);
printf("%c\n",ch);
As a simple example program using characters, consider the program to count the number of characters in a file (the standard input). The code is in count.c.
Because character I/O operations are so common in C programs, the stdio library provides two additional functions for reading and printing character variables:
ch = getchar();
reads the next character in the standard input and returns it as the value of the function. It will return EOF if detected.
putchar(ch);
is given a single character, and prints it to the standard output.
We can then modify our character counting program, count.c to use getchar() in count2.c. The input files count.dat and count2.dat are identical so you can use either one.
Note:
The %c conversion specifier and getchar() work a little differently on input than the numeric specifiers we had before (%d and %f). Where the numeric specifiers were "white space tolerant", i.e. they skipped over any leading spaces, tabs or newlines in the input, the %c specifier is not. When we use %c in scanf(), the next single character in the input is read, whatever it is, including white space characters.
That is why we had the strange behavior in the improved guess.c - the newline in the buffer after we enter the guess is read by the scanf() as the player's response. Since '\n' is not 'n', the while loop plays another game.
To fix the problem, we need to flush any extra characters from the input buffer before reading the player's answer character. We do this by reading all characters in the buffer, up to and including the '\n' character.
We have defined a macro, FLUSH, to do that:
# define FLUSH while(getchar() != '\n');
and use the macro to flush the buffer before reading the keep_playing character.