Reputation: 815
I am making a typical guessing game to learn C for the first time in my life and I noticed a bug. If you enter an integer you will get Guess a higher value
or Guess a lower value
and that works just fine. But if you put in a string, it goes insane and prints out a lot of strings saying Guess a higher value
.
What I am trying to do now is to make a check for if the user enters a string, it will say to the user something like Enter a number, not text
. How do I do this?
Is there anything you see that I can improve in this code?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main () {
int secret, answer;
srand((unsigned)time(NULL));
secret = rand() % 10 + 1;
do {
printf ("Guess a number between 1 and 10");
scanf ("%d",&answer);
if (secret<answer) puts ("Guess a higher value");
else if (secret>answer) puts ("Guess a lower value");
} while (secret!=answer);
puts ("Congratz!");
return 0;
}
Upvotes: 2
Views: 374
Reputation: 1
You may want to make a function to check if the input is numeric. Like:
int isNumeric( char *str){
while(*str)
{
if (!isdigit(*str))
return 0;
str++;
}
return 1;
}
int main(){
char guess[3];
int iGuess;
do {
printf("Guess a number between 1 and 10");
gets(guess);
if (!isNumeric(guess)){
printf("Invalid input");
continue;
}
iGuess = atoi(guess);
if (iGuess<secret)
printf("Higher");
else if (iGuess>secret)
printf("Lower");
} while (secret!=iGuess);
printf("Congrats");
return 0;
}
You need to include ctype.h and string.h
Upvotes: 0
Reputation: 61910
Check the return value of scanf
. It will return the number of items successfully matched and assigned. In this case if you enter a string then it will not be matched and assigned, but the string stays in the input buffer, and the scanf
tries to read it in each iteration and fails, and thus the problem arises.
You may change the code to:
int main () {
int secret, answer;
srand((unsigned)time(NULL));
secret = rand() % 10 + 1;
do {
printf ("Guess a number between 1 and 10");
if (scanf ("%d",&answer) != 1)
{
printf ("\nPlease enter an integer\n\n");
scanf ("%*s");
continue;
}
if (secret<answer) puts ("Guess a higher value");
else if (secret>answer) puts ("Guess a lower value");
} while (secret!=answer);
puts ("Congratz!");
return 0;
}
Note that inside the if
the line scanf ("%*s");
is done. In the %*s
the *
is the input supression indicator, this tells that a string (stands for %s
) will be read but the *
tells that although the string will be read from the input, it will be discarded. This is being done to simply discard the previously entered string which is not read by the scanf ("%d",&answer)
. In case you do not discard the string in the buffer, it will remain, and each iteration the scanf ("%d",&answer)
will fail to match any integer, as it will encounter the leftover string in the input buffer.
On the other hand you may read a string and convert the string to an integer.
Like as below:
int main () {
int secret, answer;
char buff[128];
srand((unsigned)time(NULL));
secret = rand() % 10 + 1;
do {
printf ("Guess a number between 1 and 10");
scanf ("%s",buff);
if ((answer = atoi (buff)) == 0)
{
printf ("\nPlease enter an integer\n\n");
continue;
}
if (secret<answer) puts ("Guess a higher value");
else if (secret>answer) puts ("Guess a lower value");
} while (secret!=answer);
puts ("Congratz!");
return 0;
}
atoi ()
will convert a string to an integer (in 10 base). If the characters which comprises the integer does not contain valid digits, it will return 0
. Checking for it we can detect if the user entered correctly. Also because your application needs to enter an integer within 1 and 10 therefore 0 is not included, therefore it is okay to take 0 as an invalid. To get better control on detecting an invalid integer format, and the location of the error in the string use strtol ()
Upvotes: 0
Reputation: 64414
You are ignoring the return value of scanf
, which will tell you if the conversion went well or not. scanf
will return the number of items assigned, so if it returns 1 you know that answer
was assigned to a number. If it returns 0, you know that something went wrong.
Upvotes: 1
Reputation: 111150
What I am trying to do now is to make a check for if the user enters a string, it will say to the user something like Enter a number, not text. How do I do this?
scanf
does formatted input. You may also want to check out advanced formatting specifiers in scanf
-- such as ignoring parts of the input, specifying buffer size for reading in strings, specifying only a particular set of characters that you want to read etc. If you want to verify input, you are probably best of reading a line from the console using fgets
and then parsing the line.
Is there anything you see that I can improve in this code?
You may want to improve your random number generation algorithm. Read the C FAQ.
Upvotes: 0