2

I want to write code that checks if the user enters correct input, i.e 1, 2, 3 or 4. Otherwise, the message "input error" is printed. If the user enters a letter for example, since the input variable in the scanf is char type, it works too. But in the case of multiple characters, I throught about the following solution: I try to enter all the characters into a char array and to check how many members into it. I wrote the following code:

char option;
int countIn;
char inArray[10];

do { //while option!=4
    scanf("%c", &option);

    while (countIn < 10 &&  scanf("%c", &option) != -1 && option != '\n') {
        inArray[countIn] = option;
        countIn++;
    }

    if (countIn > 1) { option = 10; }
    else { option = inArray[0]; }
    countIn = 0;
} while (option != '4');

The problem is when I enter 1 for example, the program works well, but for the second loop iteration, the scanf doesn't work and the program does automatically the part 1 again and again.

what did I do wrong?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Juliette
  • 65
  • 7

1 Answers1

5

Replace both scanf() calls with:

scanf(" %c", &option);

Note the space in the format string, which tells scanf to consume all the whitespaces. The reason why it seems to skip is the newline left in the input buffer by previous input.

From scanf():

   ·      A sequence of white-space characters (space, tab, newline,
          etc.; see isspace(3)).  This directive matches any amount of
          white space, including none, in the input.

Note that even though EOF is typically defined as -1, it's not safe to assume so. I would strongly suggest to use EOF instead of -1.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • @I3x Thanks for your answer. I tried this option but it doesn't work... When I enter 1 in scanf at the first time, the program doesn't continue and is stucked there. – Juliette Dec 17 '15 at 21:50
  • You have two successive scanf calls. One outside the loop and one in the loop condition. So it requires two successive inputs. I don't fully understand you have two loop and both operate on `option`. If you can clarify what your code is supposed to solve, I can provide a better solution. – P.P Dec 17 '15 at 21:54
  • Thanks.. I have to write a menu and the user has to enter his choice 1,2,3 or 4. Otherwise, input error message is printed.I have to provide all possible cases. I throught about it; in the case the input is a number , it is enough to write a default case, in the case the input is a letter, if I use a char input variable, it works too. And the last case, when the user enters an expression longer than one character, so I through about this solution. I hope it was clear enough... – Juliette Dec 17 '15 at 22:42
  • @Juliette You can do something [like this](http://ideone.com/dmA5f5) to validate the input number. – P.P Dec 17 '15 at 23:05
  • [Suggested code](http://ideone.com/dmA5f5) has weaknesses: If user types '\n', there is no feedback to detect that empty line.When EOF from scanf(), you could have an infinite loop. – chux - Reinstate Monica Dec 18 '15 at 02:15
  • @I3x Thanks for your help how I can substitute getchar? I can't use it we didn't learn it in the class... – Juliette Dec 18 '15 at 06:18
  • @chux so do you know how I can fix it? – Juliette Dec 18 '15 at 06:20
  • @Juliette You can another scanf instead of getchar(): `while ( (scanf("%c", &ch))!=EOF && ch != '\n');`. ` – P.P Dec 18 '15 at 07:14
  • @chux `%d` will ignore whitespaces. So it's ok when the user is expected to input a number. Perhaps, adding 'printf("Input a number: ");` will give an appearance that it's at the same promt until a number is given. '\n' will fall into else clause and considered as invalid input. The only problematic case is when user sends EOF for the outer scanf() and inner loop will require an input to break. I don't think there'll ever be an infinite loop. But OP says he can't use gethchar(), fgets() etc but only scanf()!. – P.P Dec 18 '15 at 07:22
  • @Juliette You should also change the type of `ch` to `char`: `int ch;` --> `char ch;`. – P.P Dec 18 '15 at 09:36
  • @I3x Thanks a lot!!! It works !! Can you explain me please why ch should be char? – Juliette Dec 18 '15 at 09:54
  • @Juliette `getchar()` returns an `int` whereas `scanf()` with `%c` expects an address to char. – P.P Dec 18 '15 at 09:55
  • "'\n' will fall into else clause and considered as invalid input. " is incorrect with `if ( scanf("%d", &option) != 1) ... else ...`. `scanf("%d"...` will not return is a user enters `'\n'`, it will wait for more user input. – chux - Reinstate Monica Dec 18 '15 at 15:57
  • @chux Just to clarify. I already acknowledged this when I said: "%d will ignore whitespaces. So it's ok when the user is expected to input a number. Perhaps, adding printf("Input a number: "); will give an appearance that it's at the same promt until a number is given". "\n' will fall into else clause and considered as invalid input." <-- This one was response to your comment "If user types '\n'..". I thought you mean user inputs \n *literally*. – P.P Dec 18 '15 at 16:27