This question already has answers here:
Check if input is integer type in C
(16 answers)
Closed 8 years ago.
I am working on code for one of my classes and I have hit a wall. I need the user to input a number that will be used as the number of times a for loop will be repeated. The first loop where I ask for this number is a while loop. I need to make sure the value entered is a number and not a letter or special character.
I do not know how to make sure that it is not a letter or special character.
The next problem is making sure that the for loop only runs for the specified number of times that is the number provided in the first loop.
This is what I have written so far.
#include <stdio.h>
int main()
{
int num_of_scores, n;
char enter;
float score=-1, total=0, average;
do
{
printf("\n\nEnter the number of quiz scores between 1 and 13: ");
scanf ("%d, %c", &num_of_scores, &enter);
}
while(num_of_scores<1 || num_of_scores>13/* && enter == '\n'*/);
printf("\nStill Going!");
for(n=0; n<num_of_scores; n++)
{
printf("\nEnter score %i: ", n+1);
scanf ("%f", &score);
while(score>=0 || score<=100)
{
total = total + score;
score = -1;
break;
}
}
average = total / num_of_scores;
printf("\nThe average score is %.0f.\n\n", average);
return 0;
}
So I have edited the code a little bit. There is a part in the first while loop that is in a comment which i removed because it made the program end after that loop. The printf("still going") is just a test to make sure the program gets that far. Any further pointers? I am still not sure how to check make sure a number is not entered. I though adding the && enter == '\n' would do it, but if it hangs the program it is no good. Many of the examples you have suggested are good, but i find them a little confusing. Thanks!
I'd check Check if input is integer type in C for the answer to this...
Check the return value of scanf. Per the man page:
RETURN VALUE
These functions return the number of input items successfully matched and assigned, which can be fewer than provided
for, or even zero in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching
failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see
ferror(3)) is set, and errno is set indicate the error.
do{
char ch = 0;
num_of_scores = 0;
printf("\nEnter the number of quiz scores between 1 and 13: ");
if(scanf("%d%c", &num_of_scores, &ch)!=2 || ch != '\n'){
int ch;
while((ch=getchar())!='\n' && ch !=EOF);
}
} while(num_of_scores<1 || num_of_scores>13);
Related
Task:
Create a number guessing game where the user has a limited number of guesses to figure out what the randomly generated number is
Check whether the user has inputted a digit or character using "Isdigit" informing them to input a number between 1 and 20 if they use the wrong input or guess out of the expected range.
Using a while loop limits the user guesses
After the user runs out of guesses close the program
Problem I'm facing: I'm new to programming and so I don't have too much experience yet. It's my first time trying to understand the is digit function and I feel like there is a more efficient way of solving this problem.
Since I'm using 2 data types when trying to compare int's and chars I can't make a direct comparison but I figured out the difference between char 1 and int 1 is 48 apart so I made that as a temporary solution. But it only works for single-digit numbers
I've read that I might be able to go through the string character by character to make sure each of them are a digit before the input is accepted and combine the string at the end but I'm not sure how to do that
The user can't input more than 1 character or the program ends
I'd also like to fix any other bugs people may find and write the code in a more effective and understandable way
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int main()
{
int iRandomNum = 5; //setting up a number as a placeholder until Code works
char guess; //char being used as I beleive it needs to be char for isdigit to function
int guessCount = 0; //
int guessLimit = 3;
int outOfGuess = 0;
srand(1-10);
//iRandomNum = (rand()%20)+1;
while (guess != iRandomNum && guessCount != 3 && outOfGuess == 0){ //Intended to break out of loop once any variable is satisfied
if(guessCount< guessLimit){
printf("\n%d", iRandomNum);
printf("\nYou have %d guesses left", guessLimit- guessCount); //extra user info
printf("\nGuess the number between 1 - 10: ");
scanf(" %s", &guess);
if (isdigit(guess)==0)
{
printf("\nEnter a digit!");
guessCount++; //supposed to limit user to 3 chances
}else
{ //need help solving this
printf("\nYou entered %d\n", guess - 48); //Using for testing
guess = guess - 48;
if (guess == iRandomNum) //I dont think functions as char and int are different data types
{
printf("\nYou've Won");
break;
}else{
printf("\nWrong guess");
guessCount++;
}
}
}else //Once user runs out of guesses while loop should break an then display following data
{
printf("Second else");
guessCount++;
//outOfGuess = 1;
}
}
if (outOfGuess == 1){
printf("\nOut of guesses!");
}
else{
printf("\nCongratulations!");
}
return 0;
}
An issue not already mentioned in comments: guess is used in the while condition before it has been assigned a value - that's an error.
Regarding the main problem:
In order to allow the user to input more than 1 character (i. e. up to two for a two-digit number), you can use a sufficiently sized character array. Of course you then have to account for a second character when checking using "Isdigit". So e. g. replace
scanf(" %s", &guess);
if (isdigit(guess)==0)
with
char s[2+1]; // +1 for string-terminating null character
if (scanf(" %2s", s) < 1 || !isdigit(s[0]) || s[1] && !isdigit(s[1]))
In order to convert the string in the array to an integer, you can simply use atoi:
guess = atoi(s);
I'm trying to make a program where the user inputs value to an array. What is actually required is that the program should validate against a char character. So if the user inputs a random char such as 'n' the program should tell him "You introduced a char, please input an integer: ".
How is that possible to make that without using a char variable?
for (i = 1; i <= size; i++) {
printf("Introduce the value #%d of the list: ", i);
scanf("%d", &list[i]);
if () { // I'm blocked right in this line of code.
printf("What you tried to introduce is a char, please input an integer: ");
scanf("%d", &list[i]);
}
Thanks in advance.
As #MFisherKDX says, check the return value of scanf. From the scanf man page:
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in
the event of an early matching failure.
The value EOF is returned if the end of input is reached before either
the first successful conversion or a matching failure occurs. EOF is
also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set
indicate the error.
So capturing the return value of scanf in an int variable and then comparing that variable to 1 (in your case, because you are only attempting to read 1 item) should tell you if scanf successfully read an integer value.
However, there is a nasty pitfall when using scanf that you should be aware of. If you do type n at the prompt, scanf will fail and return 0, but it will also not consume the input you typed. Which means that the next time you call scanf, it will read the same input (the n character you typed), and fail again. And it will keep doing so no matter how many times you call scanf. It always amazes me that computer science educators continue to teach scanf to students, given not only this potential pitfall, but several other pitfalls as well. I wish I had a nickel for every hour that some CS student somewhere has spent struggling to get scanf to behave the way their intuition tells them it should. I'd be retired on my own private island by now. But I digress.
One way around this particular pitfall is to check if scanf failed, and if so, to purposely consume and discard all input from stdin up to and including the next newline character or EOF, whichever comes first.
First let's look at some unfixed code that causes an infinite loop if you enter a non-integer as input:
// Typing the letter 'n' and hitting <Enter> here causes an infinite loop:
int num, status;
while (1) {
printf("Enter a number: ");
status = scanf("%d", &num);
if (status == 1)
printf("OK\n");
else
printf("Invalid number\n");
}
The above code will (after you type n and hit <Enter>), will enter an infinite loop, and just start spewing "Invalid number" over and over. Again, this is because the n you entered never gets cleared out of the input buffer.
There are a few possible ways to get around this problem, but the consensus seems to be that the most portable and reliable way to do so is as follows:
// Fixed. No more infinite loop.
int num, status;
while (1) {
printf("Enter a number: ");
status = scanf("%d", &num);
if (status == 1)
printf("OK\n");
else {
printf("Invalid number\n");
// Consume the bad input, so it doesn't keep getting re-read by scanf
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) ;
if (ch == EOF) break;
}
}
The function scanf() will returns the number of elements read, so in this case it will return 1 every time it reads an int and 0 when it reads a char, so you just need to verify that return value.
Keep in mind that after reading a character it will remain in the buffer so if you use the scanf() command again it will read the character again and repeat the error. To avoid that you need to consume the character with while(getchar() != '\n');
With that in mind I modified your code so that it works properly printing an error message if a character is introduced and asking for a new int.
for (int i = 1; i <= size; i++) {
printf("Introduce the value #%d of the list: ", i);
while (!scanf("%d", &list[i])) { //verifies the return of scanf
while(getchar() != '\n'); //consumes the character in case of error
printf("What you tried to introduce is a char\n");
printf("please introduce the value #%d of the list: ", i);
}
}
This question already has answers here:
How to scanf only integer?
(9 answers)
Closed 4 years ago.
I want to know how to keep taking inputs from keyboard with this condition: If the given input is a positive number, it keeps going with the code If the given input is a negative number or a letter, it must print "insert a positive number" and then ask again for another input until it has the correct one. About negative and positive inputs the code i wrote works great, but it bugs out when I put a letter. The check I tried is the following
chk=isalpha(n);
while(!chk || n<0)
{
printf("Inserire un intero positivo \n");
scanf("%d", &n);
chk=isalpha(n);
}
printf("%d\n%d\n", t1, t2);
In this case if I put a negative number it works correctly, but if I type a letter the printf loops. I also tried while(isalpha(n) || n<0) And a bunch of other pieces of code I'll skip for you. Please help me figure this out
You can check return value of scanf in case of char it returns 0 along with that you need to clear the buffer to stop scanf consuming the same character.
Example:
int ret = 0;
do
{
char c;
while ((c = getchar()) != '\n' && c != EOF) { } /* to clear the bad characters*/
printf("Inserire un intero positivo \n");
ret = scanf("%d", &n);
}while(!ret || n<0);
I'm trying to do a program with a simple game for a user to guess the number. My code is below:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 30
#define TRYING 5
void guessnumber(int, int, int *);
int main(void) {
int mytry = 1;
guessnumber(MAX, TRYING, &mytry);
if (mytry <= TRYING)
printf("Congratulations! You got it right in %d tries\n", mytry);
else
printf("Unfortunately you could not guess the number in the number of tries predefined\n");
printf("End\n");
return EXIT_SUCCESS;
}
void guessnumber(int _n, int _m, int *_mytry) {
srandom(time(NULL));
int generated = 0, mynum = 0, test = 0;
generated = rand() % (_n + 1);
printf("Welcome to \"Guess the number\" \n");
printf("A number between 0 and %d was generated\n", _n);
printf("Guess the number:\n");
while (*_mytry <= TRYING) {
test = scanf(" %d", &mynum);
if (test != 1 || mynum < 0 || mynum > MAX)
printf("ERROR: please enter a valid number \n");
else
if (mynum > generated)
printf("Wrong! The number your trying to guess is smaller\n");
else
if (mynum < generated)
printf("Wrong ! The number your trying to guess is bigger\n");
else
break;
*_mytry = *_mytry + 1;
}
}
Okay, now the program is working pretty ok except for one thing: the scanf test.
It works if I try to enter a number out of my range (negative or above my upper limit) but it fails if I for example try to enter a letter. What it does is that it prints the message of error _m times and then it prints "Unfortunately you could not guess the number in the number of tries predefined" and "End".
What am I doing wrong and how can I fix this?
In case, a character is entered, you're trying to detect it correctly
if(test!=1 ......
but you took no action to correct it.
To elaborate, once a character is inputted, it causes a matching failure. So the input is not consumed and the loop falls back to the genesis position, only the loop counter is increased. Now, the previous input being unconsumed, is fed again to the scanf() causing failure once again.
This way, the loop continues, until the loop condition is false. Also, for every hit to scanf(), as unconsumed data is already present in the input buffer, no new prompt is given.
Solution: You need to clean the input buffer of existing contents when you face a failure. You can do something like
while ((c = getchar()) != '\n' && c != EOF);
to clean the buffer off existing contents.
When you enter a letter, scanf() leaves the letter in the input stream since it does not match the %d conversion specifier. The simplest thing to do is use getchar() to remove the unwanted character:
if (test != 1) {
getchar();
}
A better solution would be to use fgets() to get a line of input, and sscanf() to parse the input:
char buffer[100];
while (*_mytry<=TRYING)
{
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
fprintf(stderr, "Error in fgets()");
exit(EXIT_FAILURE);
}
test=sscanf(buffer, "%d", &mynum);
if(test!=1 || mynum<0 || mynum>MAX)
printf ("ERROR: please enter a valid number \n");
else if(mynum>generated)
printf("Wrong! The number your trying to guess is smaller\n");
else if(mynum<generated)
printf("Wrong ! The number your trying to guess is bigger\n");
else
break;
*_mytry=*_mytry+1;
}
In the above code, note that the leading space has been removed from the format string. A leading space in a format string causes scanf() to skip leading whitespaces, including newlines. This is useful when the first conversion specifier is %c, for example, because any previous input may have left a newline behind. But, the %d conversion specifier (and most other conversion specifiers) already skips leading whitespace, so it is not needed here.
Additionally, your code has srandom() instead of srand(); and the call to srand() should be made only once, and probably should be at the beginning of main(). And, identifiers with leading underscores are reserved in C, so you should change the names _m, _n, and _mytry.
I am new to C programming. I have been writing this code to add numbers and I just need help with this one thing. When I type the letter 'q', the program should quit and give me the sum. How am I supposed to do that? It is currently the number 0 to close the program.
#include <stdio.h>
int main()
{
printf("Sum Calculator\n");
printf("==============\n");
printf("Enter the numbers you would like to calculate the sum of.\n");
printf("When done, type '0' to output the results and quit.\n");
float sum,num;
do
{
printf("Enter a number:");
scanf("%f",&num);
sum+=num;
}
while (num!=0);
printf("The sum of the numbers is %.6f\n",sum);
return 0;
}
One approach would be to change your scanf line to:
if ( 1 != scanf("%f",&num) )
break;
This will exit the loop if they enter anything which is not recognizable as a number.
Whether or not you take this approach, it is still a good idea to check the return value of scanf and take appropriate action if failed. As you have it now, if they enter some text instead of a number then your program goes into an infinite loop since the scanf continually fails without consuming input.
It's actually not as straightforward as you'd think it would be. One approach is to check the value returned by scanf, which returns the number of arguments correctly read, and if the number wasn't successfully read, try another scanf to look for the quit character:
bool quit = false;
do
{
printf("Enter a number:");
int numArgsRead = scanf("%f",&num);
if(numArgsRead == 1)
{
sum+=num;
}
else // scan for number failed
{
char c;
scanf("%c",&c);
if(c == 'q') quit = true;
}
}
while (!quit);
If you want your program to ignore other inputs (like another letter wouldn't quit) it gets more complicated.
The first solution would be to read the input as a character string, compare it to your character and then convert it to a number later. However, it has many issues such as buffer overflows and the like. So I'm not recommending it.
There is however a better solution for this:
char quit;
do
{
printf("Enter a number:");
quit=getchar();
ungetc(quit, stdin);
if(scanf("%f", &num))
sum+=num;
}
while (quit!='q')
ungetc pushes back the character on the input so it allows you to "peek" at the console input and check for a specific value.
You can replace it with a different character but in this case it is probably the easiest solution that fits exactly what you asked. It won't try to add numbers when the input is incorrect and will quit only with q.
#Shura
scan the user input as a string.
check string[0] for the exit condition. q in your case
If exit condition is met, break
If exit condition is not met, use atof() to convert the string to double
atof() reference http://www.cplusplus.com/reference/cstdlib/atof/