-1

I am trying to do a simple scanf and printf in the C program below:

  1. getting the user input
  2. checking if the user input is correct, if so, printing it out, else displaying a error message

Here is the code:

#include <stdio.h>

int main() {  
    int latitude;
    int scanfout;
    int started = 1;

    puts("enter the value:");

    while (started == 1) {
        scanfout = scanf("%d", &latitude);
        if (scanfout == 1) {
            printf("%d\n", latitude);
            printf("ok return code:%d\n", scanfout);
            puts("\n");
        } else {
            puts("value not a valid one");
            printf("not ok return code:%d\n", scanfout);        
        }
        fflush(stdin);
    }
    return 0;
}

Tried compiling and running it at a command terminal, program works. command line output:

enter the value:
1
1
ok returncode:1

0
0
ok returncode:1

122.22
122
ok returncode:1

sad
value not a valid one
not ok returncode:0

As you can see, the program simply scans the user input and prints it out, it works fine in command line, but when it try to redirect the input to a text file say:

test < in.txt

the program doesn't work and the print statements in the else part goes on printing in an infinite loop. The text file in.txt contains a single value 12, instead of printing 12, the program simply goes into a infinite loop and prints:

value not a valid one
not ok returncode:0
value not a valid one
not ok returncode:0
value not a valid one
not ok returncode:0
value not a valid one
not ok returncode:0

Can anyone help me with this? Is the code correct, why it works from command line and why file redirection doesn't work? help would be appreciated...

Jeya Suriya Muthumari
  • 1,947
  • 3
  • 25
  • 47
Govardhan Murali
  • 91
  • 1
  • 1
  • 8
  • Your program does not handle incorrect (non-integer) input correctly. Nothing much to do with the redirection. `scanf` does not consume the non-matching input. And `fflush(stdin)` does not do that either (it's Undefined Behaviour on some platforms and on Linux it only flushes any buffered data not the unread data). – kaylum Dec 16 '15 at 23:30
  • Try using `fgets` and then `sscanf` or `strtol` instead. – kaylum Dec 16 '15 at 23:33
  • kaylum,Thanks for your response,you were saying that the program doesnt handle incorrect data correctly,but when running the exe and if i give a dummy value: sadsdfs or some incorrect data,it does print the code inside the else part,the problem is only occuring when i try to redirect the input to a file instead of a user input,it would be really helpful if you can correct the code and show me the part which is wrong.. – Govardhan Murali Dec 16 '15 at 23:37
  • what exactly is in the file `in.txt` ? Preferable you should show a hexdump of that file. – Marged Dec 16 '15 at 23:40
  • The problem is `fflush(stdin)`. It's in general Undefined Behaviour and not predictable at best. It may work on a particular system but it will not always work (not portable at best) - it certainly does not work on my Linux system and invalid input from the terminal will result in the infinete loop that you see. Bottom line - avoid doing `fflush(stdin)`. See for example: [Using fflush(stdin)](https://stackoverflow.com/questions/2979209/using-fflushstdin) – kaylum Dec 16 '15 at 23:41

1 Answers1

0

You do not test for end of file: when the input file has been scanned, the program goes into an infinite loop because scanf return -1, the program complains and retries.

Incidentally, if there is data in the input file that cannot be converted to an int, the program will loop forever trying to reparse the same input in vain.

Note that fflush(stdin); is not specified in the C Standard, it may or may not do what you expect it to, especially from a file.

Here is a corrected version:

#include <stdio.h>

int main() {  
    int latitude, scanfout, c;

    puts("enter the value:");

    for (;;) {
        scanfout = scanf("%d", &latitude);
        if (scanfout == 1) {
            printf("%d\n", latitude);
            printf("ok return code:%d\n", scanfout);
            puts("\n");
        } else
        if (scanfout < 0) {
            break;   // End of file 
        } else {
            puts("value not a valid one");
            printf("not ok return code:%d\n", scanfout);        
        }
        /* read and ignore the rest of the line */
        while ((c = getchar()) != EOF && c != '\n')
            continue;
    }
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189