Infinite loop when trying to clear the input buffer - c

OK so after reading these previous questions:
Alternate method for clearing input buffer in c
How to clear input buffer in C?
I came up with a piece of code to empty the input buffer and count how many values were in the buffer, then return this number. A comparison is then made to check if the number exceeded the allowed number.
#include <stdio.h>
#include <stdlib.h>
int Empty();
int main()
{
double x;
int y=0;
while(y==0)
{
y=1;
if(scanf("%lf",&x)!=1 || Empty()>1) //checks if the value is acceppted
// and then attempts to empty
// the input buffer. I always expect
//at least 1 returned due to the
// EOF or '\n'
{
fprintf(stdout,"Invalid character(s) entered, please re-enter.\n");
y=0;
}
}
return(x);
}
int Empty()
{
int clearr,n=0;
do
{
n++;
}while((clearr=fgetc(stdin))!= EOF && clearr !='\n'); // If EOF or '\n' is reached
// it ends, returning the
//number of characters
return(n);
}
If i then run the program and enter 2 or 2.2 etc, the number is accepted and returned.
If i enter 2a, or 2 a or 2 2 etc it always catches the space/letter/etc and forces a SINGLE loop to allow you to try and reenter a value
If, however if enter the offending item, i.e the a, first then an infinite loop occurs.
This does not make sense to me as from what i understand, when the fgetc(stdin) is called it MUST pull either a character or an EOF which would signify only one item has been entered, ending the loop.

In a test if( A || B ), if A is true, B is not evaluated.
So if scanf("%lf",&x)!=1 is true, Empty() is not called and your loop continues forever.
One of the problems here is that you try to do several things at once, the advice would be:
keep things simple
no side effects
So 1) scan the input, 2) if it's ok move on, 3) if it's not flush and repeat.

If you enter a , scanf("%lf",&x) will give 0 and hence it never calls Empty.

Related

Reading until I manage to enter an integer

I'm pretty new in C, I used to work in Python, and I'm trying to see if something that I read is integer number. If not, to read until I manage to entry a number.
I did some research and I found out that the function scanf actually returns 1 if the read is done suitably, and 0 otherwise.
So, I have written this code, and I don't understand why this is an infinite loop, writing "Give an integer" on the console
#include <stdio.h>
int main() {
int a;
int b = 1;
do {
printf("Give an integer\n");
b = scanf("%d", &a);
} while (b == 0);
}
The problem with scanf() is that it stops reading when the first white space is encountered for most specifiers like "%d", so it's left in the input and that's why reading again would cause a problem if you don't discard such white space because it will then return immediately the next time you call it. There is a mandatory white space that is introduced when you press Enter or Return, the '\n' new line character (or line feed).
If you want to read an integer and make sure you did you can try like this
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int
main(void)
{
long int value; // You can adapt this to use `int'
// but be careful with overflow
char line[100];
while (fgets(line, sizeof(line), stdin) != NULL) {
char *endptr;
value = strtol(line, &endptr, 10);
if ((isspace(*endptr) != 0) && (endptr != line))
break;
}
fprintf(stdout, "%ld\n", value);
return 0;
}
read strtol()'s manual to understand this code
You could as suggested in the comments, remove the white space characters from the input, but IMHO that is harder and you would still have other problems with scanf(), like handing empty input which is not straight forward.
I don t understand why this is an infinite loop, writing "Give an intiger" on the console
The problem is that scanf() does not consume data that it cannot match against the specified format. It leaves such characters unread in the input stream. Therefore, if you try reading again from the same stream with the same format, without consuming at least one character by some other means, then you can be certain that the input will again not be matched. And again. And again.
To avoid your infinite loop, you need to consume at least one character of the non-matching input after each matching failure. There are many ways you could do that; here's a fairly simple one:
#include <stdio.h>
int main() {
int a;
do {
printf("Give an intiger\n");
if (scanf("%d", &a)) {
// breaks from the loop on a successful match or an error
break;
}
// consume the remainder of one line of input without storing it
if (scanf("%*[^\n]") == EOF) {
break;
}
} while (1);
}
That consumes the whole remainder of the line on which the non-matching input is encountered, which will yield less surprising interactive behavior for some inputs than many alternatives would.
If you've a penchant for writing terse code, or if you don't like to break out of the middle of a loop, then you might write the same thing like this:
#include <stdio.h>
int main() {
int a;
do {
printf("Give an intiger\n");
} while ((scanf("%d", &a) == 0) && (scanf("%*[^\n]") != EOF));
}
Because the && operator short circuits, the second scanf() call will be executed only if the first returns zero, and the loop will exit after the first iteration wherein either the first scanf() call returns nonzero or the second returns EOF (indicating an error).

Strange skipping concerning scanf()

I've been trying out a few things with linked lists, mostly because I wanted to find a way to determine the length of a sequence determined by user input. The problem is
Output in Terminal
[filip#filip PointerCheck]$ ./PointerCheck.o
Enter number to populate the list..
1 2 3
c
Enter number to populate the list..
Printing...
1 2 3
3
Why is the second population of the list skipped?
I have tried multiple things and I believe that the problem resides somewhere within the while-loop's condition, concerning scanf();
The list functions should be working properly because a separate call from add_to_list() does actually insert an integer within the list, and print_list() prints all of them. So I guess, it must be the while-loop, specifically scanf();
C Code
void user_input_list(void) {
int *input = NULL;
input = (int *) malloc(sizeof(int));
printf("Enter number to populate the list..\n");
while (scanf("%d", input)) {
add_to_list(*input, 1);
}
}
int main(int argc, char const *argv[]) {
int i = 0;
struct node *ptr = NULL;
user_input_list();
user_input_list();
print_list();
printf("%d\n", lenght_list());
return 0;
}
Here is the entire file, live [link] and on pastebin
It looks like you are entering a non-numeric character to signal the end of input. But, the first nonmatching character encountered by scanf() is left in the input stream. So, you need to clear the extra characters from the input stream before attempting to read from it again. The standard way to do this is:
int c;
while ((c = getchar()) != '\n' && c != EOF)
continue;
This discards the characters in the input stream until a newline or EOF is reached. Note that getchar() returns EOF in the event of an error, and a user may also input EOF, so it is necessary to test for it explicitly in order to avoid a possible infinite loop.

Meaning of line in the code (scanf)

In my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
void flushstdin()
{
int c;
while((c = getchar()) != '\n' && c != EOF);
int main () {
float a, b, c;
float s=0, ar1=0, ar2=0;
printf("Inform the value of size A.");
while(scanf("%f",&a) != 1 || a <= 0){
printf("Invalid value!");
What does "while(scanf("%f",&a) != 1 || a <=0){" means?
Well, scanf returns either the number of arguments matched in the given pattern (the %f part) read, or a -1 if an EOF was encountered (meaning end of input). Then a <= 0 should be somewhat self explanatory. These two combined this code will result in an input loop until either the user enters a value greater than 0 or nothing at all.
For more information on scanf, check out the docs: http://www.cplusplus.com/reference/cstdio/scanf/
This attempts to reads a float from stdin and checks whether the float was successfully read (scanf returns the number of arguments successfully read). If a was read successfully, it checks whether a is larger than zero. It continues until both conditions are false. The second condition will only be evaluated when the first condition is false, i.e. a has been read.
scanf() returns number of elements successfully read and in this case you are expecting the number of elements read to be 1. If the conversion fails then the value will not be 1 so you print out invalid value, the scanned value a can't be less that or equal to 0
scanf("%f",&a) is use for input value in your program , and here your condition is loop keep going until you enter 1 or nagitive value
While scanf returns a float (%f) e.g. 4.535 and stores it into variable a (&a) that is not equal to 1 or (||) a is equal to or less than zero (a<=0)

How to make the below condition fail by giving inputs through stdin

void main()
{
float x;
while(scanf("%f",&x) != 0)
printf("%f\n",x);
}
The above code takes input from stdin and keeps repeating it but how to end this? I know scanf can return EOF so if I add a check like
while(scanf("%f",&x) != EOF)
Which input from stdin can cause any of the above two condition to fail?
ctrl+d will make the program end but I want to know is there any specific input which can make this condition fail?
scanf function returns the number of input items successfully scanned.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs.
In your program always it return 1. To prove see the code..
#include<stdio.h>
main()
{
int a;float x;
while((a=scanf("%f",&x)) != 0)
printf("%f %d\n",x,a);
}
In this program a is always 1. Be cause only one value is scanned successfully.
a gets 2 for , if you scan two values.
Looking at linux manual pages:
scanf: These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
So, using your original program:
void main()
{
float x;
while(scanf("%f",&x) != 0)
printf("%f\n",x);
}
That means that if you enter anything that is not convertible, will end your program. Try it and enter any letter and hit enter
Ctrl + D or Ctrl + Z,
Similar questions already asked before:
End of File(EOF) of Standard input stream (stdin)

Why is the character count wrong after first entry?

I have written a program in C to count characters input from stdin. I wanted to use a loop to allow more than one entry. (Note: I am new to programming.)
main()
{
long nc;
int c;
int kc=1;
for (kc=1;kc<=5;kc=kc+1)
{
nc=0;
c= getchar();
while(c != '0')
{
++nc;
c=getchar();
}
printf("%1d\n",nc);
}
return 0;
}
So basically as you would guess, the loop accepts 5 entries.
PROBLEM: When I enter Sky0 the first result is all right, 3. But from then on, one is added to the count. That is entering dame0 results in a count of 5, sit0 results in a count of 4 etc.
While trying to debug the problem using prinf at various stages, I realized that after the first result the code finds the end of the input, 0, but enters the for loop NEVERTHELESS and waits for the next entry with nc as 1. That leads to the error in corresponding outputs.
Please tell where I'm going wrong? And why is it entering the loop even after sensing 0?
Greatly appreciate your help and time :)
The problem is that when you press enter, that becomes a character too (value 0x1a), and it is returned by the getchar call outside the while loop.
You could do something like:
while (getchar() != '\n') nc++;
In that way you do not even need to use a 0 to mark the end of the string.

Resources