0

I want to read one keyboard input - and depending whether it is valid or not proceed with the operation or do something else. If it's invalid the input should be repeated.

At this point I'm aware already scanf is not the tool of my desire, but that here would be the default-code (if scanf would work as intended):

  char val;
  int incorrect = 0;
  printf("Do you wish to proceed?: <Yy/Nn>");
  do
  {
    incorrect = 0;
    scanf(" %c", &val); //Changed to " %c" alread from "%c"
    //getchar();        //Tried already, doesn't solve the problem
    if (!(val == 'y' || val == 'Y' || val == 'n' || val == 'N'))
    {
      printf("Invalide Input!\n");
      incorrect = 1;
    }
  } while (incorrect);

The problem is if instead of a one-character input there is a longer input the error-message will be repeated by the number of the characters. Also, if instead of for instance 'n' the input is "nasdlfjas" it is still considered as a valid input.

Changing the scanf to val = getchar(); if (kind != EOF) (with or without the EOF-part) as suggested here doesn't change the behavior. But the Error-message is added right after the question.

The "GetStuff()" from this solution suffers from the same problem. The error-output is multiple and one single correct character in the whole input determines the result. This variant however is doing better, but evaluates the result on the first character of the entire string.

Other variants which include a while((c = getchar()) != EOF); which is the preferred variant to use getchar have similar issues of going through the loop-body before the input of the character (and therefore printing the error).

I decided to read a string instead of a character and then just evaluate the result by dealing with the string itself. Something like:

do{
    int c, line_length = 0;
        int i = 0;
        while ((c = getchar()) != EOF && c != '\n' && line_length < MAX_LINE - 1)
        {
            sentence[i++] = c;
            line_length++;
        }
        // String Stuff 
        if (!(val == 'y' || val == 'Y' || val == 'n' || val == 'N'))
        {
            printf("Invalide Input!\n");
          incorrect = 1;
        }
} while (incorrect);

But again there will "Invalide Input!" be printed before entering anything. What exactly would be the proper way to evaluate just the input of a single character?

Qohelet
  • 1,459
  • 4
  • 24
  • 41
  • After reading all that I'm still not clear what your exact problem is. Are you saying you want to check that only a single character has been entered? If so, can't you just check how many characters were read before proceeding to other validation? It would help if you give the exact input, expected result and actual result. – kaylum Nov 04 '20 at 23:27
  • I assume you're using a POSIX-like OS (e.g. `linux` or `freebsd`). If so, the _kernel's_ TTY driver will [normally] _not_ pass back a single char immediately upon receipt [because it's in _canonical_ mode]. It will buffer up internally until it sees a newline. To _truly_ get char-at-a-time, you'll have to put the TTY driver into _raw_ mode and the do (e.g.) `char buf[1]; int len = read(0,buf,1); int chr = buf[0];`. To get the raw mode, see `man termios` and use `tcgetattr/tcsetattr` [a shortcut is `cfmakeraw`, found in *BSD]. – Craig Estey Nov 04 '20 at 23:39
  • @kaylum - in the end I did that (sorry, "String stuff" is probably not the most accurate way to describe it). My question is rater I don't know what is supposed to be the correct way to solve a one-single-character-input-evaluation-problem – Qohelet Nov 05 '20 at 09:00
  • @CraigEstey - is there any other way to accomplish that result by programming only? – Qohelet Nov 06 '20 at 20:08
  • Using `read` and `termios` _is_ the way to do it with "programming only". If you mean to do it by reconfiguring `stdio` [e.g. `fgetc` and/or `fgets`], the answer is no. See my answer: https://stackoverflow.com/questions/62668941/how-to-read-serial-with-interrupt-serial/62670017#62670017 for an example of how to read char-at-a-time from a TTY. – Craig Estey Nov 06 '20 at 20:29

0 Answers0