Check validation from user in C programming - c

This is a snippet of my code. I'm confused why is digit can't function. It should if we input character/alphabet. The line is digit print "Please enter in numeric " but it doesn't print it. I need your opinion about this.
This my code:
printf("\nenter the amount of food to be purchased : ");
scanf("%d", &b);
printf("\n");
if (b >= 0) {
for (a=1; a<=b; a++){
printf("the price of food of- %d \t : ",a);
scanf("%d", &c);
printf("\n");
if (isdigit(c)) {
printf("Please enter in numeric !!\n");
while ((getchar()) != '\n');
system("PAUSE");
goto cashier;
}
printf("the amount ordered \t : ");
scanf("%d", &d);
printf("\n");
if (isdigit(d)) {
printf("Please enter in numeric !!\n");
while ((getchar()) != '\n');
system("PAUSE");
goto cashier;
}

scanf("%d", &c);. Reads an integer to c. When you call isdigit(c), you are not checking whether the input string is a number, you are checking whether the number inputted corresponds to an ascii character that represents a digit. This is not the intended behavior. What you want is this:
while (scanf("%d", &c) != 1) // Repeatedly get input until scanf reads 1 integer.
{
while (getchar()!='\n'); // Clear stdin.
puts("Please enter a number!");
}
// The resulting number is now stored in c.
This will try to read a number (not a string) into c. If the user does not enter 1 number, scanf() will not return 1 and the loop will try again. make sure that c is declared as an int and not a char, else numbers above 128 will overflow.

Related

C program, getting the integer value of a character. Why everything comes out after line 10?

Hi I am new to programming and I got a trouble when I try to make a little change to the example in the book.
/* Chapter 3 Example, C Prime Plus */
#include <stdio.h>
int main(void)
{
char Letter, ch;
int intValue;
printf("Please enter a letter: \n");
scanf("%c", &Letter); /* user inputs character */
printf("The code for %c is %d.\n", Letter, Letter);
printf("Now is another we to implement the process: \n");
printf("RN, the value of ch is %c, and the value of intValue is %d\n", ch, intValue);
printf("Please enter a letter: \n");
scanf("%c", &ch);
intValue = ch;
printf("The code for %c is %d.\n", ch, intValue);
return 0;
}
When I run it, the outcome would be
Please enter a letter:
M
The code for M is 77.
Now is another we to implement the process:
RN, the value of ch is , and the value of intValue is 0
Please enter a letter:
The code for
is 10.
and the part
"
Now is another we to implement the process:
RN, the value of ch is , and the value of intValue is 0
Please enter a letter:
The code for
is 10. " will all come out without asking me to enter a value.
I want to know why and are there any other way to implement it that is different from examples in the book?
Thank you for your time!
Hi Matt_C and welcome to SO.
First, you don't need the second bloc of printfs and the scanf, it just trying to do the same thing and there is an order error.
Second, it is tricky when you try consecutive scanf, it holds the last key pressed (enter is the last key pressed = \n). This is why it skips the second scanf.
There a little solution for that, add a space at the beginning of the scanfs. Try this:
int main() {
char exit, letter;
while (1) {
printf("Please enter a letter: ");
scanf(" %c", &letter);
printf("\nThe code for '%c' is %d. \n\n", letter, letter);
printf("Exit ? (y/n): ");
scanf(" %c", &exit);
if(exit == 'y')
{
break;
}
system("clear"); // UNIX
//system("cls"); // DOS
}
}
Don't forget to choose one answer that you believe is the best solution to your problem.

How do I make my if statement ask the user to try again if the input is a negative number or a letter?

How do I make my if statement ask the user to try again if the input is a negative number or a letter?
struct foodstuff {
float amount;
};
void add(struct foodstuff *tmpAdd) {
printf("Write amount: ");
scanf("%f", &tmpAdd->amount);
while (tmpAdd->amount != 0) {
if (tmpAdd->amount < -1 || isalpha(tmpAdd->amount)) {
printf("Type in a valid number!\n");
printf("Write amount: ");
getchar();
scanf("%f", &tmpAdd->amount);
getchar();
}
else {
scanf("%f", &tmpAdd->amount);
getchar();
}
}
};
I think you can rephrase your code to use a do loop instead:
do {
printf("Enter a positive number with no characters:\n");
int result = scanf("%f", &tmpAdd->amount);
while (tmpAdd->amount <= 0 || result != 1);
Note that I have removed the call to isalpha(), which acts only a single character at a time. Instead, I propose just checking that the entered number is a valid float and that it is greater than zero. If scanf does not succeed to read in a valid float, then its return value would be not be 1 and the loop would repeat. And the same is the case for entering a valid float which is a negative number.
As chux said, you could first read the input with fgets() and then parse it.
Like
char buff[100], *ptr;
float f;
while(fgets(buff, sizeof(buff), stdin)!=NULL)
{
buff[strlen(buff)-1]='\0';
f=strtof(buff, &ptr);
if(errno==ERANGE)
{
printf("\nPossible overflow.");
errno=0;
continue;
}
if(f<0 || *ptr!='\0')
{
printf("Type in a valid number!\n");
continue;
}
tmpAdd->amount=f;
printf("\n%f", f);
}
Here, fgets() is used to read the input on each iteration. fgets() will return NULL upon error.
The
buff[strlen(buff)-1]='\0';
is done because fgets() will read in the trailing \n into buff as well. We modify that \n to be the \0 character denoting the end of string with buff[strlen(buff)-1]='\0';.
strtof() is used to extract the value from buff.
It is in stdlib.h.
In case buff has something other than numbers, the number part would be converted and returned by strtof() and the ptr pointer would be made to point to the first non-numeric part of buff.
So if the first character in the string pointed to by ptr is the \0 character, there were no non-numeric parts in buff.
If the input value was too large or too small to be accommodated in a float, errno would be set to ERANGE. You need to include errno.h for that.
If overflow (or underflow) occurred, we set errno to 0 and continue.
And (tmpAdd->amount<-1) would be false even if tmpAdd->amount were -1 and -1 is negative. You need (tmpAdd->amount<0) instead.
Also, your loop would exit only when tmpAdd->amount becomes 0. You could simply do
tmpAdd->amount=0;
if that would do.
Otherwise, you can add a
if(f==0)
{
break;
}
at the end of the while loop.
I did some changes to my code, it looks like this now:
printf("Write amount: ");
scanf("%f", &(tmpAdd + index)->amount);
getchar();
do {
if (tmpAdd->amount <= -1 || isalpha(tmpAdd->amount != 0)) {
printf("Type in a valid number!\n");
printf("Write amount: ");
scanf("%f", &(tmpAdd + index)->amount);
getchar();
}
else if (isdigit(tmpAdd->amount >= 0)) {
scanf("%f", &(tmpAdd + index)->amount);
//getchar();
}
} while (tmpAdd->amount <= -1 || isalpha(tmpAdd->amount != 0));
};
Main looks like this:
int main (void) {
int input, noFood = 0;
int flag = 1;
printf("Welcome to the shopping list manager. \n\n");
struct foodstuff food1;
while (flag == 1) {
printf("1 - add food\n");
printf("2 - print shopping list\n");
printf("3 - end\n\n");
printf("What do you want to do? ");
scanf("%d", &input);
clear();
switch (input) {
case 1: add(&food1, noFood); noFood++; break;
case 2: print(&food1, noFood); break;
case 3: printf("\nExiting program\n"); flag = 0; break;
default: printf("Please enter a valid choice\n");
}
}
return 0;
}
And the output like this:
Output
The only problem remaining is that when I want to add another item (add food) for the second time and I type a letter or a negative number, it doesn't run through the if statements.

How do I get my code from going into an infinte loop?

I am rewriting the Guessing Game code from 'C Programming for Absoulute Beginners' to verify that the user has entered in a digit, using the isdigit() function.
The rest of the code works, in terms of error checking; but the moment that the user enters in a non-digit, the code goes into an infinite loop.
#include <stdio.h>
#include <stdlib.h>
#define NO 2
#define YES 1
main()
{
int guessGame;
guessGame = 0;
int iRandomNum = 0;
int iResponse = 0;
printf("\n\nWould you like to play \"The Guessing Game\"?\n\n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
do{
if(guessGame == YES){
iRandomNum = (rand() % 10) + 1;
printf("\nGuess a number between 1 and 10:\n\n ");
scanf("%d", &iResponse);
if(!isdigit(iResponse)){
printf("\nThank you\n");
printf("\nYou entered %d\n", iResponse);
if(iResponse == iRandomNum){
printf("\nYou guessed right\n");
printf("\nThe correct guess is %d!\n", iRandomNum);
printf("\nDo you wish to continue? \n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
} else {
printf("\n\nSorry, you guessed wrong\n");
printf("\nThe correct guess was %d!\n", iRandomNum);
printf("\n\nDo you wish to continue? \n");
printf("\nType '1' for Yes or '2' for No!\n\n");
scanf("%d", &guessGame);
}
}
else {
printf("\nYou did not enter a digit\n");
printf("\n\nPlease enter a number between 1 and 10:\n\n");
scanf("%d", &iResponse);
}
}
else {
printf("\nThe window will now close. Try again later!\n");
exit(0);
}
}while(guessGame != NO);
}
The code goes into infinite loop as scanf() is unable to read an integer. The character you entered remains in the keyboard buffer.No more reading of integers is possible as long as the character is present in the buffer. scanf() simply returns the number of items read as 0 each time. Hence,the program does not wait for the user to enter data and infinite loop results.
scanf() returns number of items successfully read. So,you can simply check for the return value of scanf(), if its 1 then scanf() has correctly read an integer.
check = scanf("%d", &iResponse);
if(check == 1){
printf("\nThank you\n");
printf("\nYou entered %d\n", iResponse);
and flush the buffer if wrong input is entered
else {
while (getchar() != '\n'); //flush the buffer
printf("\nYou did not enter a digit\n");
printf("\n\nPlease enter a number between 1 and 10:\n\n");
//scanf("%d", &iResponse);
}
no need to ask for input here, while loop will continue and prompt for input in the beginning
Trying taking the input in the form of string .. also u will have to compare the input in the form 'number' :)

Force input to be positive numbers only with error handling in C

I have a trivial question to ask. My program should take postive integers only. If there is anything illegal, the user should be prompted to input a number again.
The code I have for now is:
#include<stdio.h>
int main(){
int reads;
int num=0;
char a;
while(num<=0){
printf("Please Enter positive integer: ");
while(((reads = scanf("%d%c", &num, &a)) != 2 && reads != EOF) || a != '\n' ){
do {
printf("Please Enter positive integer: ");
reads = scanf("%c", &a);
}while(reads != EOF && a != '\n');
}
}
printf("Num is: %d", num);
}
The code above almost did what I want; however, when the input is multiple letters, the output prompts will be print multiple times, which bothers me a lot.
Please Enter positive integer: pdesf
Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: dfwerasdfwe
Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only: Enter positive numbers only:
I'd appreciate if you can help me fix this or offer better solutions for this seemly trivial problem. Thanks ahead!
Use fgets to read a whole line into a buffer. If you only want to process the first character, you can just ignore the rest. Something along the lines of:
char buf[MAX_LINE_LEN];
if (fgets(buf, MAX_LINE_LEN, stdin))
{
char a = buf[0];
/* Do handling... */
}
else
{
/* error */
}
Coded in browser, may contain traces of error.
while(num<=0){
printf("Please Enter positive integer: ");
while(((reads = scanf("%d%c", &num, &a)) != 2 && reads != EOF) || a != '\n' ){
printf("Please Enter positive integer: ");
while(getchar() != '\n');
}
}
i have solved your program. Try the following program in Turbo C++:
#include<stdio.h>
#include<conio.h>
main()
{
char n[2],ni;
clrscr();
GET:
printf("Enter positive number: ");
scanf("%s",&n);
if(atoi(n)>0)
{
printf("You have entered ");
ni=atoi(n);
printf("%d",ni);
}
else if(atoi(n)<=0)
{
printf("Wrong choice\n");
goto GET;
}
else
{
printf("Wrong choice\n");
goto GET;
}
getch();
}

i have to use getchar(); twice to end program [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why doesn't getchar() wait for me to press enter?
I continue to learn C, and at this stage I have something that is not clear to me.
When I write a program, that has several printf();, at the end, where I ask a user to press Enter key to finish the program, I have to write getchar(); twice, because when I write it once it does not work. I use getchar(); only at the end of the program, nowhere else.
I work on Ubuntu. I write in C.
here is my latest work:
#include<stdio.h>
main()
{
int m,n,r,k,q,l;
printf("This program will help you to find GCD & LCM of 2 non-negative integers\n");
printf("Now, you'll be asked to enter your integers, press Enter to continue");
getchar();
printf("Enter first integer:");
scanf("%i", &m);
printf("Enter second integer:");
scanf("%i", &n);
while(m<0 || n<0)
{
printf("The integers cannot be negative! You'll be asked to enter integers again.\n");
printf("Enter first integer:");
scanf("%i", &m);
printf("Enter second integer:");
scanf("%i", &n);
}
while(m==0 && n==0)
{
printf("Both of the integers cannot be zero at the same time! You'll be asked to enter integers again.\n");
printf("Enter first integer:");
scanf("%i", &m);
printf("Enter second integer:");
scanf("%i", &n);
}
if(n>m)
{
int b;
b=n;
n=m;
m=b;
}
r=m%n;
if(r==0)
{
printf("The GCD of these integers is %i\n", n);
printf("The LCM of these integers is %i\n", m);
printf("Press Enter to finish");
getchar();
getchar();
return 0;
}
k=n%r;
while(k>0)
{
r=k;
k=q;
}
l=(m*n)/r;
printf("The GCD of these integers is %i\n", r);
printf("The LCM of these integers is %i\n", l);
printf("Press Enter to finish");
getchar();
getchar();
return 0;
}
The reason you need 2 getchar() is because
the last scanf() call left the ENTER waiting in the buffer
the 1st getchar() "ate" that ENTER
the 2nd getchar() waits for input.
To properly deal with user input, use fgets() and sscanf() instaed of the simpler scanf(). Define a buffer for these functions, for example
char buffer[1000];
and then replace your scanf() calls with the pair
fgets(buffer, sizeof buffer, stdin);
sscanf(buffer, "%d", &n);
In the future you might want to also check the return value of sscanf() to detect invalid inputs, like foo42ENTER
if (sscanf(buffer, "%d", &n) != 1) /* invalid input */;
Edit (using strtol() rather than sscanf() is even better -- thanks to #Scooter)
char buffer[1000];
char *err;
/* ... */
fgets(buffer, sizeof buffer, stdin); /* error checking ommited */
n = strtol(buffer, &err, 10);
/* error checking ommited */
/* ... */

Resources