1

How could one handle the following scenario. The User is asked to input his command:

  1. the user inputs only a digit for example 1
  2. the user inuts a string for example hello
  3. the user inuts a string for example hello 1 2

The Terminal could look like

Enter: 1 -- programm do somehting(not important)
Enter: hello -- programm do somehting(not important)
Enter: hello 1 2 -- programm do somehting(not important) 

My Code

   printf("Enter:");
   scanf("%[^\n]s", command_player);
   getchar()

  for(size_t i = 0; i < strlen(command); i++) 
        {
          if(isdigit(command[i]))
          {
            has_digit = 1;
          }
          if(isalpha(command[i]))
          {
            has_letter = 1;
          }
        }

and then 

if(has_digit == 1 && has_letter == 0)
//do something
if(has_digit == 0 && has_letter == 1)
//do something
if(has_digit == 1 && has_letter == 1)
//do something

However I have the problem that if I enter in one of the ifs another datatype as it is stated my programm crashes

anthropos
  • 13
  • 4
  • The `scanf("%[^\n]s", command_player);` is a "beginner's error". The format `%[...]` isn't a subset of `%s` but a distinct specifier with its own behaviour, such as how it handles whitespace. I suggest you use `fgets()` to obtain every input, and apply `sscanf()` or other functions to the string. – Weather Vane May 29 '22 at 14:35

1 Answers1

1

You can achieve your goal by reading the input line with fgets() and trying to parse it with sscanf() in different ways:

#include <stdio.h>

int main() {
    char buf[256];
    char word[256];
    int n1, n2;
    char endc;

    // loop for ever: equivalent to while (1) {}
    for (;;) {
        // output the prompt        
        printf("Enter: ");

        // flush the output to make sure if is visible:
        // output is normally line buffered, but the prompt does
        // not end with a newline so it is still in the stdout buffer
        // most systems will flush the output when a read operation
        // is requested, but some don't so `fflush(stdout)` ensures
        // the prompt is visible on all systems.
        flush(stdout);

        // read a line of input, and break from the loop at end of file
        if (!fgets(buf, sizeof buf, stdin))
            break;

        // try matching different input patterns:
        // `sscanf()` returns the number of successful conversions,
        if (sscanf(buf, "%d %c", &n1, &endc) == 1) {
            // `sscanf()` returned `1` if there is exactly a number
            // preceded and/or followed by optional whitespace
            // but no further character.
            printf("user entered a single number %d\n", n1);
        } else
        if (sscanf(buf, " %255[a-zA-Z] %c", word, &endc) == 1) {
            // this second `sscanf()` returns 1 if there is exactly
            // a single word (a sequence of uppercase or lowercase
            // letters) with optional initial and training whitespace.
            printf("user entered a single word %s\n", word);
        } else
        if (sscanf(buf, " %255[a-zA-Z] %d %d %c", word, &n1, &n2, &endc) == 3) {
            // this third `sscanf()` returns 3 if there is exactly
            // a word followed by 2 numbers with optional initial 
            // and training whitespace.
            printf("user entered a word %s and 2 numbers %d and %d\n",
                   word, n1, n2);
        } else {
            printf("user input does not match a known pattern: %s", buf);
        }
    }
    return 0;
}

The format strings can be extended to include other characters for the words and modified to match other input patterns.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Thank you, would you be so kind and explain it a little bit. As I understood it your for(;;) would be like a while(1) then you flush the buffer -- which would have the same logic as my getchar. Then you check if fgets was able to read in, but I dont get how the first sscanf skips to the second if its not a digit. – anthropos May 29 '22 at 15:04
  • @anthropos: I amended the answer with detailed explanations. The second `sscanf()` is run only if the first does not match a number, and so on. – chqrlie May 29 '22 at 16:30