Taking a beginning programming class and learning C. This is the first significant obstacle I've run into, was at it for 6 hours yesterday and couldn't find a solution, so I gave up and decided to ask for help. Assignment is to build a number guessing game (haven't yet gotten to the random number generation part) with a loop based on a boolean, where the user is prompted after a correct guess to play again and answer y or n. I've tried a bunch of stuff, and the loop either terminates regardless of the option chosen (which is what it does in its current state), or loops endlessly regardless, and I'm not sure what I'm doing wrong. Here's my code. Thanks in advance.
#include <stdio.h>
#include <stdbool.h>
int main()
{
int num = 5; /* temp placeholder for testing */
int guess;
char* response;
bool running = true;
while (running)
{
printf("Guess a number: ");
scanf("%d", &guess);
if (guess < num)
{
printf("That's too low.\n\n");
}
else if (guess > num)
{
printf("That's too high.\n\n");
}
else
{
printf("That is correct.\n\n");
guess = 0;
printf("Play again? (y/n): ");
scanf(" %c", response);
printf("Response: [%s]", response);
printf("\n");
if (response == "y")
{
running = true;
}
else
{
running = false;
}
}
}
return 0;
}
CodePudding user response:
You are confusing strings with a single character. Here you have response declared as a pointer to a char.
char* response;
change that to
char response;
change
scanf(" %c", response);
to - this is passing in the address of the one character variable. %c accepts one character.
scanf(" %c", &response);
Change
if (response == "y")
to
if (response == 'y')
string literals use double-quotes. Also if you actually wanted to compare strings, that is not the correct way either, and you should look at the strcmp() function.
CodePudding user response:
The first issue to be aware of is that ==
is not defined for strings (or other array types) - response == "y"
doesn't work like you'd expect1.
To compare strings, you need to use the strcmp
library function:
if ( strcmp( response, "y" ) == 0 ) // strcmp returns 0 if the strings match
{
// do something
}
The second issue is that you're confusing your types. You declare response
as a char *
, meaning that it's meant to store the address of another char
object, not a character value. However, you never initialize it to point to a char
object - its value is indeterminate, and it's pointing somewhere random. When you call scanf
with it, you're writing the input value to some random location which in your case just happens to be writable and not "important" (in the sense that it doesn't cause your code to crash immediately).
You most likely want to do it the way OldProgrammer showed - change the type from char *
to char
, change the scanf
call to use &response
, and change the test to response == 'y'
(single instead of double quotes).
Alternately, you can treat response
as a string - in that case, you'd declare it as an array of char
, large enough to hold your response plus the string terminator - in this case, 2 elements:
char response[2]; // 'y' or 'n' plus a string terminator
Instead of using scanf
(which is prone to buffer overflows if you aren't careful), we'd use fgets
instead:
if ( !fgets( response, sizeof response, stdin ) )
// input operation failed, handle as appropriate
else
// process response
and then as I said above, you'd use strcmp
for the comparison:
if ( strcmp( response, "y" ) == 0 )
// process yes response
else
// process no response
Interestingly, you got the format string right for reading a single character (most new C programmers don"t). Unlike most conversion specifiers, %c
won't skip over any leading whitespace, and more often than not people wind up reading stray newlines rather than the input they intend. Putting the blank before it in " %c"
tells scanf
to skip over any leading whitespace.
- What it's actually doing is comparing the address value stored in
response
to the address of the first character of the string literal"y"
. The only way that expression will ever be true is ifresponse
stores the address of the literal"y"
.