loop fails to terminate despite providing appropriate input - c

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);
}

Related

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

How to make a loop which ignores letters in 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;

My code repeats more than requried while loop

The problem is that when i type any character except for y or n it display this message two times instead to one)
This program is 'Calculator'
Do you want to continue?
Type 'y' for yes or 'n' for no
invalid input
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main ()
{
//program
//first to get two numbers
//second to get choice
int x=0,y=0,n=0;
char choice;
//clrscr(); does no work in devc++
system("cls"); //you may also use system("clear");
while(x==0)
{
puts("\t\tThis program is 'Calculator'\n\n");
puts("Do you want to continue?");
puts("Type 'y' for yes or 'n' for no ");
scanf("%c",&choice);
x++;
if(choice=='y')
{
y++;
puts("if this worked then we would continue to calculate the 2 no");
}
else if(choice=='n')
exit(0);
else
{
puts("invalid input");
x=0;
}
}
getch();
}
`
it looping twice because enter(\n) character is stored in buffer use scanf like this(add space before %c)
scanf(" %c",&choice);
That is because of the trailing new line after you enter y or n and hit enter key.
Try this out:
scanf("%c",&choice);
while(getchar()!='\n'); // Eats up the trailing newlines
If you input any character other than 'y' or 'n', control enters the :
else
{
puts("invalid input");
x=0;
}
block, which resets x to 0, Now the loop condition :
while(x == 0)
is true and hence it enters the loop again.
Also you may want to skip the trailing newline character while reading like :
scanf(" %c", &choice );

calling main function in C

#define f(x) (x*(x+1)*(2*x+1))/6
void terminate();
main()
{
int n,op;
char c;
printf("Enter n value\n");
scanf("%d",&n);
op=f(n);
printf("%d",op);
printf("want to enter another value: (y / n)?\n");
scanf("%c",&c); // execution stops here itself without taking input.
getch();
if(c=='y')
main();
else
terminate();
getch();
}
void terminate()
{
exit(1);
}
In the program above , I want to take input from the user until he enters an n value.
For this I'm trying to call main() function repeatedly . If it is legal in C , I want to know why the program terminates at the scanf("%c",&c) as shown in commented line.
Someone , please help.
You should never call main from within your program. If you need to run it more then once use a while loop inside it.
Your execution stops because by default stdin in a terminal is line buffered. Also you are not using the return value from getch.
int main()
{
int n,op;
char c;
do {
printf("Enter n value\n");
scanf("%d",&n);
op=f(n);
printf("%d",op);
printf("want to enter another value: (y / n)?\n");
scanf("%c",&c);
} while (c == 'y')
return 0;
}
You first have
scanf("%d",&n);
which you have to press the Enter key for it to accept the number.
Later you have
scanf("%c",&c);
There is a problem here, which is that the first call to scanf leaves that Enter key in the input buffer. So the later scanf call will read that.
This is easily solved, by changing the format string for the second scanf call just a little bit:
scanf(" %c",&c);
/* ^ */
/* | */
/* Note space here */
This tells the scanf function to skip leading whitespace, which includes newlines like the Enter key leaves.
It's legal, but you'll have a STACKOVERFLOW after a while (pun intended).
What you need is a loop:
while (1) {
printf("Enter n value\n");
scanf("%d",&n);
op=f(n);
printf("%d",op);
printf("want to enter another value: (y / n)?\n");
scanf("%c",&c); // execution stops here itself without taking input.
getch();
if(c != 'y')
break;;
}

Loop skips a scanf statement after the first time

Here is the code for main():
int main (void)
{
float acres[20];
float bushels[20];
float cost = 0;
float pricePerBushel = 0;
float totalAcres = 0;
char choice;
int counter = 0;
for(counter = 0; counter < 20; counter++)
{
printf("would you like to enter another farm? ");
scanf("%c", &choice);
if (choice == 'n')
{
printf("in break ");
break;
}
printf("enter the number of acres: ");
scanf("%f", &acres[counter]);
printf("enter the number of bushels: ");
scanf("%f", &bushels[counter]);
}
return 0;
}
Every time the program runs through the first scanf works fine but on the second pass through the loop the scanf to enter a character does not run.
Add a space before %c in scanf. This will allow scanf to skip any number of white spaces before reading choice.
scanf(" %c", &choice); is the only change required.
Adding an fflush(stdin); before scanf("%c", &choice); will also work. fflush call will flush the contents of input buffer, before reading the next input via scanf.
In case of scanf(" %c", &choice); even if there is only a single character in the input read buffer, scanf will interpret this character as a valid user input and proceed with execution. Incorrect usage of scanf may result in a series of strange bugs [like infinite loops when used inside while loop].

Resources