How to make a loop which ignores letters in C? - c

C noob here. Just ignore the title couldn't find a better one :D
void displayMainMenu() {
int choice;
do {
printf("1. Start the game.\n");
printf("2. Recruit troops.\n");
printf("3. Exit.\n");
scanf("%d", &choice);
} while (choice < 1 || choice > 3);
switch (choice) {
case(1) : printf("...");
break;
case(2) : printf("...");
break;
case(3) : printf("...");
exit(0);
break;
}
}
When I enter a a number out of the range it loops perfectly fine, but when I enter a letter or a symbol, it gets to an infinite loop. I want my programs to be perfect even though I am a beginner so I was wondering how can I achieve this? Should I use ASCII or is there a complete different method of doing this kind of thing.
Thanks very much for your help!

scanf("%d", &choice);
scanf("%*[^\n]%*c");//add

Reason why it goes infinite: the scanf rejects a letter for "%d" and nothing's read. Notice that didn't consumes the letter in the input buffer, so the next time scanf is invoked it fails again.
To know more about this, check the return value of scanf: 0 or EOF for nothing read, 1 for 1 item read.
So the solution would be to examine the return value of scanf and break out of the loop.
EDITED:
An example added:
do {
printf("1. Start the game.\n");
printf("2. Recruit troops.\n");
printf("3. Exit.\n");
int item_got = scanf("%d", &choice);
if (item_got != 1)
{
choice = -1; // mark it.
break;
}
} while (choice < 1 || choice > 3);

As scanf() function returns 0 if fails to read formatted input. So if you want to exit when user enter this kind of input then you can write:
if(!scanf("%d", &choice))break;

Related

In C scanf skips read int value

I am trying to creating a console program with menu in c. But I have a problem about validating the option int value. When I put char value it accepts it. I am trying to catch this condition. It understands the condition but scanf is not working second time to read input. It just skips. My code below. Thanks for help!
while (true) {
printf("%s", "Choose one option: ");
while (scanf("%d", &choice) != 0) {
puts("This is not a number! Enter again:");
}
// checking input
while (choice < 1 || choice > 8){
puts("Wrong input! You can choose only 1 - 8!");
printf("%s", "Choose one option: ");
scanf("%d", &choice);
}
if (choice == 8)
break;
(*options[choice])();
}

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' :)

Logic Error in C Program on xcode

I have written this code for a grocery store.. This code makes perfect sense to me. However, I keep getting a logic error. Every time the user enters a bill and then presses -1 to exit, he is taken back to the main menu. When user presses choice 2 to EXIT program, the program is NOT exiting and he taken back to case 1 for some reason. Could you please help me? Thank you!
#include <stdio.h>
int main(void){
double prices[7];
prices[0]=2.55;
prices[1]=12.07;
prices[2]=2.00;
prices[3]=0.55;
prices[4]=5.35;
prices[5]=8.65;
prices[6]=2.55;
int choice;
int productCode;
int quantity;
char stop[3];
int compare;
double price;
double totalPrice=0;
do{
printf("\n1. Create new bill");
printf("\n2. EXIT");
printf("\n\nEnter choice: ");
choice=scanf("%d", &choice);
switch(choice){
case 1:{
do{
printf("\nEnter product code: ");
scanf("%d",&productCode);
printf("\nEnter quantity of product: ");
scanf("%d",&quantity);
price=prices[productCode]*quantity;
totalPrice=totalPrice+price;
printf("\nTo stop entering products enter -1.. to continue press any other character ");
scanf("%s", &stop);
compare=strcmp(stop, "-1");
}while(compare!=0);
break;
}
case 2: break;
default: printf("\nInvalid choice");
}
}while(choice!=2);
getchar();
return 0;
}
Instead of
choice=scanf("%d", &choice);
Do
scanf("%d", &choice);
scanf return value is:
On success, the function returns the number of items of the argument
list successfully filled. This count can match the expected number of
items or be less (even zero) due to a matching failure, a reading
error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while
reading, the proper indicator is set (feof or ferror). And, if either
happens before any data could be successfully read, EOF is returned.
If an encoding error happens interpreting wide characters, the
function sets errno to EILSEQ.
http://www.cplusplus.com/reference/cstdio/scanf/
for (;;){
printf("\n1. Create new bill");
printf("\n2. EXIT");
printf("\n\nEnter choice: ");
scanf("%d", &choice);
if(choice == 2 ){
break;
} else if(choice == 1){
do{
printf("\nEnter product code: ");
scanf("%d",&productCode);
printf("\nEnter quantity of product: ");
scanf("%d",&quantity);
price=prices[productCode]*quantity;
totalPrice=totalPrice+price;
printf("\nTo stop entering products enter -1.. to continue press any other character ");
scanf("%s", &stop);
compare=strcmp(stop, "-1");
}while(compare!=0);
} else {
printf("\nInvalid choice");
}
}

I cannot seem to loop again after selecting default in switch case in C

hello guys I coded something like kfc menu,and I got it to work(finally),but when I input something other than numbers for "menu",eg:the letter "A", I just can't get it to loop again to normal,instead it finishes the program
#include <stdio.h>
#include <stdlib.h>
int main()
{
char counter='y';
float totalprice=0;
while (counter=='Y' || counter=='y')
{
int menu;
float price=0;
printf("\nplease select from menu:");
scanf (" %i", &menu);
switch(menu)
{
case 1: {
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
}
case 2: {
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
}
case 3:{
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
}
default : {
printf ("\nplease enter proper number please:");
scanf("%2f", &menu);
break;
}
}
printf("\n\nadd order?(Y/N):");
scanf (" %c", &counter);
}
printf("\n\nThe total price is: %f", totalprice);
return 0;
}
You should use fgets() (reference here) first and then sscanf() (reference here), checking it's return value to see if it's a number.
char inputBuffer[MAX_BUFFER];
do
{
fgets(inputBuffer, MAX_BUFFER, stdin);
}
while(sscanf(inputBuffer, "%d", &menu) != 1)
You scanf with %f in the default case, I am fairly certain that is for floats. Use %d.
Remove scanf("%2f", &menu);
Switch in C does not support char in switch-case. Before you start switch-case validate the user input. If it is a number go into switch case otherwise display a user message to enter only numeric value
I recommend that you debug this by printing out the value of "counter" at various points in the loop (i.e. after you read it in, at the bottom of the loop, etc.). This will give you visibility into what your code is doing.
You can try something like this
#include <stdio.h>
int main()
{
char counter;
float totalprice=0;
int menu=0;
do
{
printf("\n1. one hotbox1=RM10.50");
printf("\n2. one hotbox2=RM10.60");
printf("\n3. one hotbox3=RM10.70");
printf("\nplease select from menu:");
scanf ("%d", &menu);
switch(menu)
{
case 1:
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
case 2:
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
case 3:
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
default :
printf ("\nplease enter proper number please:");
scanf("%d", &menu);
}
printf("\n\nadd more order?(Y/N):");
fflush(stdin); //to empty the input stream.
scanf("%c",&counter);
}while(tolower(counter) != 'n'); //tolower returns the lowercase character.
printf("\n\nThe total price is: %.2f", totalprice);
return 0;
}
When scanf("%i", &menu) tries to read an integer from the input, it finds A, which it cannot interpret as a number, so it does not read it(*). Then the next scanf continues reading the input from when the other left off and happily reads the letter 'A'. Since you loop as long as the read letter is either 'y' or 'Y' (which A is neither), it exits the loop.
(*) read up on the documentation of scanf to see how to tell if it encountered an error.
Note: scanf("%i", &menu) should be scanf("%d", &menu) as%d` is the formatting symbol for integers.
One solution would be to change the loop condition to:
while (counter!='N' && counter!='n')
{
...
}
This way you end the loop only if an explicit 'N' or 'n' is inputted.
Note: it won't help if you accidentally type 'n' for the menu item, so see the comment about the error handling above.

loop fails to terminate despite providing appropriate input

This program runs into an infinite loop despite providing 'n' as an input,to exit the while loop.
What could be the issue ?
#include<stdio.h>
main()
{
int num,p=0,q=0,r=0;
char check='y';
while(check!='n')
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
getchar();
printf("enter a number");
scanf("%d",&num);
if(num>0)
p++;
else if(num<0)
q++;
else
r++;
}
printf("positive=%d\t negative=%d\t zero=%d\t",p,q,r);
}
while(check!='n')
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
getchar();
printf("enter a number");
scanf("%d",&num);
The scanf("%d", &num); leaves the newline in the input buffer, thus in the next iteration of the loop, that is stored in check. After that, the getchar() consumes the 'n' or 'y' you entered. Then the scanf("%d", &num); skips the newline left in the buffer, scans the entered number, and leaves the newline in the buffer. You need to remove the newline between scanning in the number and querying whether you want a next iteration.
Above that, it would be better to exit the loop immediately after the user entered an 'n', so
while(check!='n')
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
if (check == 'n') {
break;
}
printf("enter a number");
scanf("%d",&num);
getchar(); // consume newline
would be better. That would still be open to bad things should the user input not match expectations, so if you want a robust programme, you need to check the return value of scanf to know whether the conversion was successful, and completely empty the input buffer before and after scanning in the number.
The issue is that the loop isn't exiting until the while condition is re-evaluated at the top of the loop. I'd suggest reworking your loop to something like this.
// we've purposely changed this to an infinite loop because
// we hop out on condition later
while(1)
{
printf("do you want to enter a number y or n");
scanf("%c",&check);
getchar();
// here's the code that will jump out of the loop early if the user
// entered 'n'
if('n' == check)
break;
// user didn't enter 'n'...they must want to enter a number
printf("enter a number");
scanf("%d",&num);
if(num>0)
p++;
else if(num<0)
q++;
else
r++;
}
You are not checking the character input. Here is what it should be:
printf("do you want to enter a number y or n");
scanf("%c",&check);
/* This is what you need to add */
if (check == 'y') {
getchar();
printf("enter a number");
scanf("%d",&num);
}

Resources