Input Restriction in C - c

I'm having a bit of a problem restricting the user input. I only want the integers 1,2 or 3 to be the input. Do.. while loop does the job for invalid integer inputs, but how do I disregard string/character inputs? I also need to ask the user repetitively if ever the input is invalid.
Update:
int problem;
printf("Please select the problem that you want to solve:\n");
printf("\t 1-Problem 1\n");
printf("\t 2-Problem 2\n");
printf("\t 3-Problem 3\n");
while( scanf("%d", &problem)==0 && (problem!=1 || problem !=3 || problem !=2))
{int c;
while((c=getchar())!='\n' && c!=EOF);
printf("Please select the problem that you want to solve:\n");
printf("\t 1-Problem 1\n");
printf("\t 2-Problem 2\n");
printf("\t 3-Problem 3\n");
}
It kinda looks messy because of the multiple printfs. I just don't want lengthy codes in one row. Anyway, I wanted only 1,2, or 3 as inputs. If the entered input is invalid, the program asks the user again until the user inputs a valid input.
The code works for invalid inputs such as words, letters, characters, etc. However, if the user inputs 1.2 , it proceeds with 1 which should not be the case. 0 isn't accepted either. What can I do to my code to restrict them?

scanf with a %d will fail and return 0 in case of invalid inputs(like character(s)). So, just check if the scanf failed by checking the return value of it.
while(scanf("%d",&num)==0 && (num<=1 || num >=3)) //Invalid input if this is true
{
int c;
while((c=getchar())!='\n' && c!=EOF); //Clear the stdin
printf("Invalid input. Try again\n");
}
The line
while((c=getchar())!='\n' && c!=EOF);
clears the standard input stream so that scanf does not read the invalid input again and again resulting in an infinite loop.
Note that scanf can return EOF. This will cause the program to think that the user has entered valid input. You can add a check to see if the return value from scanf isn't EOF. Also, you should initialize num to a number that is not 1,2 or 3 to avoid invoking Undefined Behavior.

Related

Check if user input is between 1 and 10

part of the program that i am working on is to get a number from the user , but the condition is that it has to be any number between 1 and 10 nothing else, so how could i force the user to only input one of these specific numbers , so that if he wrote any other number or a character , an error message to pop out and repeat the process till he choses correctly
here is the code
// getting a number from the user
int number;
printf("Please pick a number from 1 to 10 : ");
scanf("%d",&number);
printf("Oh ! You have chosen %d\n", number);
// what should i do here ?
C allows for very nice input control, but it is not free... Said differently you cannot rely on the language nor on the standard library but have to code everything by hand.
What you want:
control that the input is numeric
control that the number lies between 1 and 10
How to:
control the return value of the input function
if you got a number control its value
if you got an incorrect input (optionaly) give a message and loop asking
Possible code:
int number;
for (;;) { // C idiomatic infinite loop
printf("Please pick a number from 1 to 10 : ");
if (scanf("%d", &number) != 1) {
// non numeric input: clear up to end of line
int c; // c must be int to compare to EOF...
while ((c = fgetc(stdin)) != EOF && (c != '\n'));
}
else if (number > 0 && number <= 10) break; // correct input: exit loop
// error message
printf("last input was incorrect\n");
}
printf("Oh ! You have chosen %d\n", number);
If you want a more user friendly way, you could use different messages for non numeric input and incorrect values, but it is left as an exercise for you... (I am afraid I am too lazy ;-) )
What you likely envision is a fine-grained control over the character-by-character input of the user; for example, anything but digits should be impossible; or when they type a 2 and try to type another digit, that should be impossible, too.
That's something we know from graphic user interfaces. It requires that your program is "informed" about every key stroke at once.
For historical reasons, this capability is not part of the C standard library. The reason is that historically all kinds of input devices were used, for example punch cards or paper-based teletypes. The communication was line by line: Input was local until the user hit the aptly named "enter" key. Any stupid device can do that, a lowest common denominator which is why all languages which do not define GUI elements adhere to it.
Obviously, character-by-character input is entirely possible on modern terminals and computers; but it is system specific and has never been standardized in the language. It is also likely more complicated than meets the eye if you want to give the user the opportunity to edit their input, a phase during which it may be "illegal". In the end you'll need to catch the point when they submit the entire value and validate it, which is something you can do even with the crude facilities that C provides.
Hints for an implementation:
Let the user complete a line of input. Validate it, and if the validation fails, prompt for another attempt. Do that in a loop until the input is valid.
Use scanf because it is convenient and error free (compared to home-grown input parsing).
This is something often overlooked by beginners: Check the return value of scanf which will indicate whether the input could be parsed (read the scanf manual!).
int main()
{
int number = 0;
while (number < 1 || number > 10)
{
printf("please enter number between 1 - 10\n");
scanf("%d", &number);
if (number < 1 || number > 10)
{
printf("you entered invalid number!\n");
}
}
return 0;
}
while(1)
{
//input ....
if(number<0 || number>10)
{
// print error
continue;
} else {
while (getchar() != '\n') ;
break;
}
}
I think I made a mistake at the beginning.A character can be checked by if but scanf can't. If scanf can't get the input in the specified format, the illegal input in the input buffer will be kept all the time.
After looking at another question, I thought that when the input is wrong, we should use getchar() to clear the buffer before the next input.

While using scanf("%i",var) if the user enters a letter or just presses enter i get a problem

I want for my program to just ask again if the user entered a letter or just pressed enter.
I know that if the input is not a number scanf() will return 0, so i have been doing this:
int variable;
printf("Please write an integer and then press enter: \n");
if (scanf("%i",&variable)!= 1) { /* ERROR CODE */; return 1;}
return 0;
But i dont want for my program just to stop if the input is not correct. So i tried this:
int variable;
do
{
printf("Please write an integer and then press enter: \n");
} while (scanf("%i",&variable) != 1);
But the program will just start printing "Please write an integer and then press enter:" without stoping. Is there a way of doing this?
edit: Forgot the &
edit2: Thanks to everybody.
edit3: I have been looking into the functions. Will this code be correct?
char variable[10]; int var;
do
{
printf("Please write an integer: ");
fgets(variable,sizeof(variable),stdint);
} while( sscanf(variable,"%i",&var) != 1 );
I have tried it and it works but i post it here because i know im probably missing something.
int variable;
do {
printf("Please write an integer and then press enter: \n");
} while (scanf("%i", &variable) != 1 && scanf("%*[^\n]") == 0);
The second scanf discards characters till the '\n' character. The '\n' character remains, though it will be skipped by the first scanf on the next iteration of the loop.
The code has some defects but it will work in most cases. One defect is that, if scanf returns EOF without reading a character then the loop will exit but the value of variable will be indeterminate, which can cause undefined behaviour when used. This one is not difficult to cure. Another one is that, the behaviour is undefined if the user enter a number outside of range for int. So a way better approach, is to use fgets and strtol library functions.

Entering while loop repeatedly before stopping at getchar()

I'm writing a simple C program in which I want to validate my user's input for integers from 1-9.
The logic for my code seems fine but for some reason if I type "lll" for my input (or any other random input not between 1-9), it will show the error message inside the while loop a couple of times before actually stopping at the getchar() once again.
/**
* Validate user input and reprompt if invalid
* #return input - Users valid input
*/
int validateUserInput() {
int firstInput = getchar() - 48;
int secondInput = getchar();
while(secondInput != 10 || firstInput >= 10 || firstInput <= 0 ){
printf("Invalid Input. Please try again. \nEnter a number between (1-9): ");
firstInput = getchar() - 48;
secondInput = getchar();
}
return firstInput;
}
The logic is that:
Invalid Input - If the second input != 10 which means that the second char is something other than the enter key.
Invalid Input - If the first char subtracted 48 is higher than 9 or less than 1 then it's too high.
The logic seems fine to me but here's some output when I enter random characters:
Enter a number between 1-9: lllll
Invalid Input. Please try again.
Enter a number between 1-9: Invalid Input. Please try again.
Enter a number between 1-9: Invalid Input. Please try again.
Enter a number between 1-9: Invalid Input. Please try again.
Enter a number between 1-9: Invalid Input. Please try again.
Enter a number between 1-9: Invalid Input. Please try again.
Enter a number between 1-9:
Why does it repeat that message so many times before actually letting me enter input again? This is all that's wrong with my program.
Your logic is fine. But the invalid characters you input still remain in the input buffer. So, the subsequent calls to getchar() read them.
Whenever you hit an invalid input, you want to ignore them all. You can read them out using a loop like this:
while(secondInput != 10 || firstInput >= 10 || firstInput <= 0 ){
printf("Invalid Input. Please try again. \nEnter a number between (1-9): ");
int i;
while((i=getchar()) != '\n' && i != EOF);
...
Having said that it's generally hard to use getchar() and scanf() family functions to correctly read interactive input and do error checking. A better way would be to read lines (such as fgets()) and parse/error check them.
Because you entered 5 chars. 5x L. You are checking only one char, but by what did you wrote I guess you want to check whole input charr array. So then you cant use getChar().

How to enter a letter to quit a program in C

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/

User Input Restriction goes haywire

int problem;
printf("Please select the problem that you want to solve:\n");
printf("\t 1-Problem 1\n");
printf("\t 2-Problem 2\n");
printf("\t 3-Problem 3\n");
while( scanf("%d", &problem)==0 && (problem!=1 || problem !=3 || problem !=2))
{
int c;
while((c=getchar())!='\n' && c!=EOF);
printf("Please select the problem that you want to solve:\n");
printf("\t 1-Problem 1\n");
printf("\t 2-Problem 2\n");
printf("\t 3-Problem 3\n");
}
It kinda looks messy because of the multiple printfs. I just don't want lengthy codes in one row. Anyway, I wanted only 1,2, or 3 as inputs. If the entered input is invalid, the program asks the user again until the user inputs a valid input.
Sure, the code works for characters, string inputs but whenever 0, or any other integer or input starting with a number except for 1,2 and 3, the program does nothing. Also, if 1.2 is entered, 1 is chosen. same goes for 2.2, 2.3 which will become 2. How can I fix it?
Point 1
You need to change the logic involved in
scanf("%d", &problem)==0
because, if scanf() returns 0, then reading problem is undefined behaviour.
You need to re-think the while loop logic. Also, always initialize the local variables.
Point 2
You need to change
(problem!=1 || problem !=3 || problem !=2)
to
((problem!=1) && (problem !=3) && (problem !=2))
because, logically, you're tryning to say, if the input is not 1 and not 2 and not 3, then..., so,
You can try this code
while( scanf("%d", &problem)==0 && (problem<1 || problem >3))
It will check valid user input and also check user has entered value between 1 to 3.
condition will fail if user enter value less than 1 or greater than 3.

Resources