Why is my while loop acting this way? - c

I am currently trying to get a while loop working, but it's not going the way I want it too. What I want to do is loop until a specific input is put in. Something must be wrong with my syntax, but I can't figure out what.
#include <stdio.h>
int main()
{
float input = 0;
scanf("%f", &input);
while(input!=0)
{
printf("hello\n");
scanf("%f", &input);
}
return 0;
}
For some reason, it doesn't break out of the while loop when it is zero. I want the while loop to stop working after someone enters 0, but when someone enters 0 it will create an infinite printing of "hello" instead..As you may have guessed, input becomes 0 whenever the user inputs anything besides a float, so if I enter a letter, I am expecting the while loop to stop, but it doesn't ;\
Edit:
Thank you guys for help! I learned and figured out why my logic was wrong (due to lack of understanding how to test the value of scanf)!! Cheers.

input does not become zero if the user enters a non-float. scanf won't change the value, and it won't consume any characters. So, if the user enters a non-float, scanf will keep reading the same characters over and over again.
You can test the scanf return value to see if it successfully read anything. scanf returns the number of fields that were successfully read, so a return value of 0 means that it failed to parse anything:
while(scanf("%f", &input) == 1) {
printf("You entered %f\n", input);
}

Write the loop like
while(input!=0)
{
printf("hello\n");
input = 0.0;
scanf("%f", &input);
}

Related

Are there better ways to clear stdin when looking for a specific kind of input in C?

fairly new programmer here just trying to understand if there is a better way to do this and hoping to get some feedback.
TL;DR: Is there a better way to clear stdin when looking for a specific input?
For some background, I've been learning C for the past 3 weeks and scanf() has been our "go to" function for user input. After looking around for answers to this question, I'm beginning to learn that scanf() is not always preferred.
In this part of the assignment that I'm working on, I created this while loop that is supposed to run while the user input is a nonzero, positive integer. It took a while, but to get to this point I now understand that if a string is inputted instead of an integer when scanf("%d", &variable); is assigned while using leads to an infinite loop as stdin does not get cleared.
I tried to solve this problem by checking to see the return of the scanf() functions, and running the loop while the return is equal or less than 0 (which would mean that the scanf() function broke and did not return anything since it saw a char instead of an int).
The thing is, the code seems to work great until we encounter one scenario, which is where we have characters followed by an integer.
For example:
Input = 1
program runs with no issues
Input = string
program runs loop, asks for new valid input
Input = string string
program runs loop, asks for new valid input
Input = 123string
program proceeds, but then next loop with an int scanf() is infinite. 123 is stored as an int to variable.
My current understanding of the issue is that scanf() reads the integers until we get to the characters and then "string\n" gets stored to stdin, creating an infinite loop in the next part. To solve the issue, I added a fflush(stdin); before the next integer scanf() loop which seems to work.
So my question is: Would somebody be willing to show me some other ways to do this other than adding a fflush(stdin); line before every int scanf() loop? I'm sure there are better ways but I don't rightly know who to ask and the internet seemed like a good resource. Thank you.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int squareLen = 0;
int numColors = 0;
int infiniteLoopStop;
// Asks for user input of desired Square Length
printf("Please enter the finished side length (in inches) of one square.\n> ");
while (squareLen < 1) {
infiniteLoopStop = scanf("%d", &squareLen);
if (infiniteLoopStop <= 0 || squareLen < 1) {
printf("\nInvalid input. Enter a nonzero, positive integer.\n> ");
fflush(stdin);
}
}
// Temporary solution to problem
fflush(stdin);
// Asks for int input of colors and loops while number of colors is not 2 or 3
printf("How many colors are you using? Enter 2 or 3.\n> ");
while (numColors < 2 || numColors > 3) {
infiniteLoopStop = scanf("%d", &numColors);
if (infiniteLoopStop <= 0 || numColors < 2 || numColors > 3) {
printf("Invalid, please enter 2 or 3.\n> ");
fflush(stdin);
}
}
printf("\n");
return 0;
}

why does scanf() not work when followed by a loop?

When I enter a string in the code below, the program doesn't move on. It just allows me to keep typing and pressing enter with no effect. Why does this happen and how can I fix it.
#include <stdio.h>
main() {
char str[20];
int aaa = 0;
int exit;
printf("Enter anything: ");
scanf("%s", str);
while(aaa == 0) {
if(str[3] == 'a') {
aaa++; }
else {
scanf("%d", &exit);
if(exit == 3) {
aaa++; } } }
printf("%s\n", str);
}
Log:
Enter anything: 2/3/4444
Now
it
just
lets
me
keep
on
typing
Edit: I solved it and I’m a bit embarrassed at how simple it was. I know people have been trying to explain this to me but in my own words this is what was happening: as the condition to enter the while loop was being met the program would enter the while loop. However, unless the input entered for the scanf satisfied one of the conditions in the loop, the program had no way of leaving the loop and therefore, it would get stuck. Basically I was simply missing an else statement which solved this problem.
After a string whose fourth character is not an a, your program reads an integer. It will never attempt to read anything but an integer after that first read. So you must not enter anything but an integer after the first string.
If you want your program to handle a non-integer after the string, you need to add code to do that. You currently have none.

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/

why does my int while loop keeps going when i scan for a number?

I'm having a problem with a while loop. I have to enter a number which is bigger than 0 and below 81. when I use numbers like -1,0,1,2,82 it is going good and I get the expected result, but when I use a letter it keeps going through my while loop. I've used the debugger in eclipse and when I'm at the while loop amount is automatically set to '0' because of the failed scanf. Why does it keep looping when I insert a letter?
#include <stdio.h>
#include <stdlib.h>
int main(){
int amount = 0;
printf("Give a number:\n");
fflush(stdout);
scanf("%d",&amount);
while(amount <= 0 || amount >= 81){
printf("Wrong input try again.\n");
printf("Give a number:\n");
fflush(stdout);
scanf("%d",&amount);
}
return EXIT_SUCCESS;
}
You need to make sure the scanf() worked. Use the returned value to do that
if (scanf("%d", &amount) != 1) /* error */;
When it doesn't work (because eg a letter was found in input) you probably want to get rid of the cause of the error.
A better option to get input from users is to use fgets()
See this related question: scanf() is not waiting for user input
The reason is that when you press enter with a char, scanf failed and didn't eat up the char in the input feed. As a result, the next block begins having whatever you entered before.
You can check that by adding a getchar() before the scanf() inside the while loop. You'll notice that it'll repeat the while loop as many times as your line has invalid characters, then stop and wait for input. The getchar() ate one of the invalid chars in the input each time the loop ran.
It would be better not to use scanf like that, though. Take a look a this resource:
Reading a line using scanf() not good?

C Program causing black screen on the console

So I was coding this program and after I was done, I tried to run it but for some reason nothing shows up on the console. I went through the code multiple times and tried multiple ways of performing the same function, which is basically to keep on getting inputs from the user until he/she enters 0, then display the largest and second largest number, and if the user enters 0 and there are no numbers available then continue checking. I think may be there is an infinite loop or some other problem with it. Here is the code:
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
void main()
{
int input,z;
int large,small,counter=0;
bool a=false;
while (1){
if(scanf("%d\n",&input)>0)
{
small=input;
counter++;
if(small>large)
{
z=small;
small=large;
large=z;
}
}
else if(scanf("%d\n",&input)<0)
{
printf("Please enter a positive value\n");
}
else if(scanf("%d\n",&input)==0)
{
if(small>0 && large>0)
{
printf("There are in total %d positive integers entered",counter);
printf("The largest number is %d, while the second largest is %d", large,small);
a=true;
break;
}
else
{
printf("You have to enter atleast two positive integers");
}
}
}
}
Any sort of help would be appreciated, thank you.
The scanf function doesn't return the input, it returns how many numbers it read.
Since your code reads numbers one at a time, scanf will always return 1, causing an infinite loop.
To fix this, hoist the scanf call outside the branching code:
while (1) {
scanf("%d", &input);
if (input > 0) ...
else if (input < 0) ...
else ...
}
There are more bugs in your code (Rohan pointed out one of them) but this should solve the black screen.
Each time you check the value entered, you're doing another scanf() or trying to read a new value instead of checking the value of the number that was entered. And the value you're checking is the return value of scanf(), but the number that's entered is actually stored in your "input" variable. So yes, there are a few things going on here, but you're essentially in an infinite loop because the entered values aren't getting read or evaluated properly.
The C function scanf() doesn't take a newline. Instead use:
scanf("%d", &input);
Also, initialize your "large" variable to 0 when you define it (it's value is not 0 and will give you unpredictable results):
int large = 0, small, counter = 0;
What you want to do is ONLY one scanf() at the top of your while loop to read in a number. After that, your if's should be testing the value of "input":
while (1)
{
scanf("%d", &input);
if (input > 0) /* positive number entered */
{
/* do something */
} else if (input < 0) /* negative number entered */
{
/* print error */
} else /* no need to test value since it must be 0 at this point */
/* do stuff */
}
}
Happy C coding! ;-)
If you walk carefully through the logic of your program, you'll see it doesn't make sense. For example, if a number is entered, you never print anything.

Resources