Why code before break doesn't work? - c

int main() {
int input = 0;
do {
if(input > 1) {
printf("You entered");
break;
}
printf("Enter an integer (> 1): ");
scanf("%d",&input);
} while(input < 2);
return 0;
}
Hello, I'm new to C. Could anyone explain what break does? In this program, the statement before break "You entered" doesn't show up on the console. I know java but this works totally different.

There is no integer exist between 1 and 2. Change
if(input > 1)
to
if(input > 0)
After that if you enter 1 then program enters the if body then print You entered and on encountering the break statement, immediately terminates the do-while loop.

The "break" statement causes your code to exit the loop immediately.
You're not seeing any output because you only loop while the input is strictly less than 2, but your if statement is looking for input that's strictly greater than 1.
That's not going to work; if you enter 1, the if statement won't execute (because 1 > 1 is false), and if you enter 2, the loop exits immediately (because 2 < 2 is false).
You either need to loop while input <= 2, or you need to test for input >= 1.
Having said all that...
Standard output is usually line-buffered, meaning you won't see anything show up on your console until the buffer is full or you send a newline character. You either need to manually flush the stream or send a newline as part of the format string; either
printf("You entered");
fflush(stdout);
or
printf("You entered\n");
should work.

Related

C program loops infinitely after scanf gets unexpected data

I have a program where I want the input integer to be between 2 and 64 inclusive, so I put scanf inside a do { ... } while loop. Here's the code I initially tested:
int initialBase;
do {
printf("Initial base: ");
scanf("%i", &initialBase);
} while (initialBase < 2 || initialBase > 64);
The problem is whenever the input is not a valid integer, it just outputs the printf statement indefinitely and no longer prompts for user input, instantly flooding the console. Why is that happening and what's a better way of reading input that satisfies the conditions I want?
When scanf() fails, the argument is not automatically initialized, and uninitialized values could be any value, so it might be less than 2 or greater than 64 no one knows.
Try this
int initialBase;
/* some default value would be good. */
initialBase = 2;
do {
printf("Initial base: ");
if (scanf("%i", &initialBase) != 1)
break;
} while ((initialBase < 2) || (initialBase > 64));
the check will break out of the loop if you input something that is not a number, the initialiazation of initialBase is just a good habit which in your case could have prevented the behavior you describe, but in this case it's there to prevent accessing an uninitialized value after the while loop.
The reason the loop didn't stop, was because scanf() leaves some characters in the input stream when they are not matched, and calling scanf() again while those characters are still there will make scanf() keep waiting for valid input, but returning immediatly with the currently invalid input that is in the stream, if you want to keep reading, try reading characters from the stream until a '\n' is found, this way
int initialBase;
initialBase = 0;
do {
printf("Initial base: ");
if (scanf("%i", &initialBase) != 1)
{
while (fgetc(stdin) != '\n');
continue;
}
} while ((initialBase < 2) || (initialBase > 64));

While loop stuck infinitely with else statement, despite using continue

I'm currently trying to get a users input and see if it is valid, i.e whether or not they have entered an integer versus a string, however, my program does work in realizing the user hasn't entered an integer given it goes to the else statement, except it doesn't restart the loop but rather just prints the words "please try again" a million times in a infinite loop. I've tried implementing the continue statement, but it seems to create the same issue, any input would be much appreciated!
Here is a snippet:
int userInput;
int exit;
exit = 0;
while(exit == 0)
{
if(scanf("%d",&userInput) == 1)
function(userInput);
else
printf("Please try again!\n"); //This loops infinite times, doesn't restart the loop and check input again like the first if
continue;
}
Just add
scanf("%*s");
Inside the body of the else to remove the invalid input from the stdin. You might also want to set exit to 1 when scanf is successful in order to prevent an infinite loop. So modify your code to:
int userInput;
int exit;
exit = 0;
while(exit == 0)
{
if(scanf("%d",&userInput) == 1) {
function(userInput);
exit=1;
}
else
{
printf("Please try again!\n");
scanf("%*s");
}
}
See this answer: https://stackoverflow.com/a/3852934/3788
The original code loops indefinitely because the invalid data (the
"gfggdf") is not removed from the input buffer when scanf fails to
convert it to an integer -- it's left in the input buffer, so the next
call to scanf looks at the same data, and (of course) still can't
convert it to an integer, so the loop executes yet again, and the
results still haven't changed.

Do while loop not exiting despite expression becoming false

I've got a program here which contains a do-while loop within a specified void method. I'm trying to exit the loop within the function, so that the do-while loop actually works as it is supposed to. Except after I run the program and one of the cases occurs, the program continues to run despite my while statement stating that it should only work while(userInput != 1).
I cannot use global variables to solve this problem, as my assignment limits me on using such techniques, thus any help would be much appreciated!
Here is a snippet of my code:
void functionTest()
{
int gameOver = 0;
int userInput;
do
{
printf("please enter a number 1-3");
scanf("%d",&userInput);
switch(userInput)
{
case 1:
printf("You entered %d",userInput);
gameOver = 1;
break;
case 2:
printf("You entered %d",userInput);
gameOver = 1;
break;
case 3:
printf("You entered %d",userInput);
gameOver = 1;
break;
}
}
while(gameOver!= 1);
}
}
The problem probably lies when you use scanf(). Something that you're inputting before hitting enter is not 1, 2 or 3. Could you tell us exactly what you type when it asks you to enter a choice?
Sometimes, the standard output needs to be flushed before using a fresh scanf(). Try fflush(stdout) before the scanf line.
See older question 1 and older question 2.
EDIT:
I can reproduce the problem easily enough if I enter anything apart from "1","2" or "3"...
I would suggest, you do the following before executing the switch statement:
Add fflush(stdout) before scanf()
Accept the input as a string (%s) instead of a number. (char [] needed)
Trim the string of trailing and leading white spaces.
Convert to number using a library function
Then switch-case based on that number
The problem is that if other characters (that aren't part of an integer) are present in the input stream before an integer can be read, scanf() fails and unusable data is never cleared out... which leads to an infinite loop (where scanf() repeatedly fails to read the same characters as an integer, over and over).
So you need to read off the invalid characters when scanf() fails, or as part of the format.
A simple fix would be to change your scanf from:
scanf("%d",&userInput);
to:
scanf("%*[^0-9]%d",&userInput);
to read (and discard) any characters in the input stream that aren't digits 0-9 before reading your integer... but that still doesn't check whether scanf fails for any other reason (like a closed input stream).
You could replace it with something like this:
int scanfRes,c;
do {
scanfRes = scanf("%d",&userInput); /* try to read userInput */
/* ..then discard remainder of line */
do {
if ((c = fgetc(stdin)) == EOF)
return; /* ..return on error or EOF */
} while (c != '\n');
} while (scanfRes != 1); /* ..retry until userInput is assigned */
..which will retry scanf() until the field is assigned, discarding the remainder of the line after each attempt, and exiting the function if fgetc() encounters an error or EOF when doing so.

how does a do while loop used provide user prompt?

I made a simple program to make a half- triangle representing with # everything works fine only thing is that my do while loop in not working not able to prompt the user quick help?
#include<stdio.h>
int main() {
int n;
do {
printf("enter a non negitive number less than equal to 23");
scanf("%d\n",&n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
{
if(j <= n-(i+2) )
printf(" ");
else
printf("#");
}
printf("\n");
}
}
while(n < 23);
printf("thanks for using my program");
return 0;
}
As stated in the comments, your problem is that it prints output even when you enter a number over 23. (I am repeating this because this information is not present in the question itself.)
This is because the condition is evaluated at the end of a do ... while loop. You need to test the condition immediately after reading the input if you want to exit immediately after the number is read.
Try encapsulating the print-and-read logic in a function; this will make it easier to use as the condition in a while loop.
int prompt_and_read(int * output) {
printf("enter a non negitive number less than equal to 23: ");
fflush(stdout);
return scanf("%d\n", output);
}
Then you can do this:
while (prompt_and_read(&n) && n < 23) {
....
}
This is an improvement in multiple ways:
It flushes the output in order to make sure that the prompt gets displayed. printf() may not flush the output until a newline is written.
The loop will terminate immediately if it reads a number 23 or larger.
Because you were not checking the return value of scanf(), if the input ended before a number 23 or larger was read, the loop would continue infinitely. Testing the result of scanf() fixes this by terminating the loop if no input could be read.
If you're asking what I think you're asking...
Standard output is line-buffered, meaning output won't appear on the console until the buffer is full or you send a newline or you manually flush with fflush().
Try the following:
printf("enter a non negitive number less than equal to 23: ");
fflush( stdout );
scanf("%d",&n);
The call to fflush will force the output to appear on your console.

Infinite loop in C when entered character [duplicate]

This question already has answers here:
Skipping over Scanf statement in C
(4 answers)
Closed 8 years ago.
I am writing an objective c program for hangman. I need to replicate another program which has been given to me. I have done most of it, but am having an issue. It has to replicate the other program exactly, so I went into the other one and entered a character into the wordlength. It came up with the "number must be between 3 and 14 (inclusive)" statement, and asked me to enter a number again, but it started to loop infinitely. It works when i enter a number lower than 3 and larger than 14 (comes up with the error and asks for another input) but with a letter it infinitely loops. Also, the loop is meant to loop infinitely until the word length is larger than 3 and less than 14. That is why the while loop will loop infinitelyAny ideas??? Thanks
while (i == 0) {
printf("\n\n > Please enter a word length: ");
scanf("%i", &wordLength);
printf("\n\n");
if (wordLength > 3 && wordLength < 14) {
continue;
}
else printf("number must be between 3 and 14 (inclusive)");
}
The main problem (that you seem to be asking about) here is that you don't check for errors from the scanf call. It will return with the number of successfully scanned items, or zero if none were scanned, or EOF on error.
If scanf fails to extract data from the input, like when you ask for an integer but the user write a letter, then that letter will continue to be in the input buffer, so the next call to scanf will see that letter again. And again and again...
The best way to fix this is to read the whole line, as text, into a buffer, and then try to parse the integer from this buffer (using e.g. sscanf):
char input[16];
if (fgets(input, sizeof(input), stdin) == NULL)
{
printf("Error reading your input\n");
exit(0); /* Do whatever error handling you want */
}
if (sscanf(input, "%d", &wordLength) != 1)
{
printf("Error: Input was not a valid integer\nPlease try again: ");
fflush(stdout);
continue;
}
Problem is with while (i == 0){ you never change i in the loop. You may want to update it to
while (wordLength == 0){
But make sure you do wordLength=0 before the loop.
change the value of i for the loop to terminate. you dint change the value of i anywhere inside loop.
continue;
will not exit the loop, it will just skip the statement after continue statement and start the loop again. To exit the loop use
break;
so use break or change the value of i to some value other than i=0 to exit the loop.
I think you meant break instead of continue:
if (wordLength > 3 && wordLength < 14)
break;
break will take you out of the loop, whereas continue skips to the next iteration of the loop (which , as others have mentioned, never terminates because i is never changed)
Do not forget to break your loop when the condition is met.
while ( 1 ){
printf("\n\n > Please enter a word length: ");
scanf("%i", &wordLength);
printf("\n\n");
if (wordLength > 3 && wordLength < 14) {
break;
}
else printf("number must be between 3 and 14 (inclusive)");
}

Resources