One problem is the combination of:
char question, n, y;
scanf("%s", &question);
You are using %s
to read a null-terminated string into a single character. Even if you hit 'y' and return, you'll be overwriting beyond the end of the variable. This is not good. (The good news is that "%s"
skips over white space, including the newline after the number).
You either need to use "%c"
in the format:
char question;
scanf(" %c", &question); // NB: The leading space is important!
or you need to use a string format and a string variable (and no &
):
char question[10];
scanf("%9s", question);
If you use an array, you need to consider whether to use strcmp()
, or whether to compare the first character from the input:
while (strcmp(question, "n") == 0);
while (question[0] == 'n');
You probably got told by the compiler that you'd not declared variable n
so you added it. You probably need the loop to end with while (question == 'n'
);and then get rid of the (now) unused variable
n(and the currently unused variable
y`).
Note that if you use omit the space in the " %c"
format string:
scanf("%c", &question);
then it will normally get the newline after the number, which won't be 'n'
, so your loop will exit every time, apparently without waiting for you to enter anything. You can finesse that with scanf(" %c", &question);
which skips white space before reading a character.
You should test that scanf()
received the input you expected each time you use it. The correct test for single item inputs is:
if (scanf(" %c", &question) != 1)
...input failed...
If you need to distinguish between EOF and conversion failure, you can capture the return from scanf()
:
int rc;
if ((rc = scanf(" %c", &question)) != 1)
...rc == EOF on EOF; rc == 0 on 'conversion failure'...
...a single character input can't easily fail...
...but if someone types 'a' instead of '9' when you're looking for a number...
Getting I/O right using scanf()
is distressingly hard. Many experienced programmers simply don't use it; it is too hard to get right. Instead, we use fgets()
or POSIX getline()
to read a line of data, and then use sscanf()
to parse it. There are many advantages to this, but a primary one is that the newline has been eaten so you don't run into problems with the variable question
not containing the answer you expect.