1

The purpose of this code is so if the user enters an incorrectly formatted input, the program while ask the user to try again. For some reason though in my code, the scanf is constantly skipped after the first iteration, causing in infinite loop

#include <stdio.h>
int main() {
double A1;
int n1, loopchck, i=0;
while (i==0) {
    printf("Enter a real number and inerger (A n): ");
    fflush(stdin);
    loopchck=scanf_s(" %lf %d", &A1, &n1);
    if (loopchck == 2) {
        i = 1;
    }
    else {
        i = 0;
    } 
} 
return 0;
}
  • 2
    `fflush(stdin);` is UB, remove that. – Sourav Ghosh Feb 23 '16 at 17:30
  • 2
    in failure case, you need to cleanup stdin.... – Sourav Ghosh Feb 23 '16 at 17:31
  • 1
    You're not calling the standard function `scanf` but instead `scanf_s`, which must be a custom function. The issue is possibly related to what that function does. – Nate Eldredge Feb 23 '16 at 17:32
  • 1
    Also related: you know that stdout is usually line buffered on terminals, right? So there's a good chance that your printf won't actually cause anything to appear on the screen. You maybe wanted to `fflush(stdout)`. – Nate Eldredge Feb 23 '16 at 17:33
  • @SouravGhosh: What do you mean, "cleanup stdin"? – Nate Eldredge Feb 23 '16 at 17:33
  • What environment are we dealing with? – sjsam Feb 23 '16 at 17:37
  • re the 1st comment: http://stackoverflow.com/a/22902085/2757035 "working by analogy, people often think that fflush(stdin) should discard any unused input, but if you think about it a little bit that doesn't make much sense." – underscore_d Feb 23 '16 at 17:42
  • 1
    `scanf()` is constantly skipped after the first iteration because the bad input is **still there**. If input was bad for `scanf()`, why do you think calling the same code again will return different results.? You need additional code to consume the offending input. – chux - Reinstate Monica Feb 23 '16 at 17:43

1 Answers1

0

For a start, lets think about what you want fflush(stdin); to do. fflush only operates on streams that have been written to; it causes any unwritten (cached) data to be fully written, and it makes no sense in the context of stdin.

This is a common mistake. When you tell scanf to read an integer (or a floating point, whatever) it'll stop reading when it no longer sees anything numeric. This means you'll probably have a leftover '\n' on the stream, at least. The user might have also entered other (erroneous) input that you want to discard.

The idea of discarding user input is horrible! You should think about accepting input in a different form (e.g. using argv in int main(int argc, char **argv)) to make their uncomfortable life a little more comfortable.

If you can't do that (or you don't want to), you can use one of the following pieces of code to discard up to (and including) the next '\n':

void fdiscardline(FILE *f) {
    int c;
    do {
        c = fgetc(f);
    } while (c != EOF && c != '\n');
}

void fdiscardline(FILE *f) {
    fscanf(f, "%*[^\n]");
    fgetc(f);
}

You should use this after your input, not before. Also, you need to think about what i should be. Should it be zero when more input can be read (e.g. while (i==0)), or zero when input wasn't read correctly? You need to be consistent because that's your loops terminal condition. For example:

#include <stdio.h>
int main() {
    double A1;
    int n1, loopchck, i=0;
    while (i==0) {
        printf("Enter a real number and inerger (A n): ");
        loopchck=scanf_s(" %lf %d", &A1, &n1);
        fdiscardline(stdin);
        if (loopchck == 2) {
            i = 0;
        }
        else {
            i = 1;
        }
    } 
    return 0;
}
autistic
  • 1
  • 3
  • 35
  • 80