-1

I am writing this code:

int b;
char c;

scanf("%d", &b);

while((c = getchar()) != EOF) {
    if(c >= 9 || c < 0) {
        printf("Invalid number!\n");
        exit(0);
    }
}

When I assign b, automatically c is equal to b. For example, if my input for b is 10, it automatically goes into the if-statement and exits the code.

Does anyone know why?

Anton Menshov
  • 2,031
  • 8
  • 22
  • 37
david
  • 1
  • 1
    Check the return value from `scanf` and go from there – Ed Heal Mar 15 '21 at 22:17
  • 2
    `getchar` returns an `int`. You cannot reliably check for EOF if `c` is not of type `int`. – William Pursell Mar 15 '21 at 22:17
  • If your input file is text, it is extremely likely that `c >= 9` is true. Perhaps you meant `if( c >= '9' || c < '0')` which is very different than `if( c >= 9 || c < 0)` – William Pursell Mar 15 '21 at 22:19
  • What input did you provide? Did you provide input for `scanf` and `getchar` on separate lines? If so, `getchar` will be reading the unread newline left behind from `scanf`. [Just avoid using `scanf`](http://c-faq.com/stdio/scanfprobs.html). – jamesdlin Mar 15 '21 at 22:20
  • `while (scanf("%d", &b) != 1) { fputs ("error: invalid integer input.\n", stderr); for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {} }` – David C. Rankin Mar 15 '21 at 23:31
  • A few links discussing the proper use of `scanf`, [C For loop skips first iteration and bogus number from loop scanf](https://stackoverflow.com/a/60472657/3422102) and [Trying to scanf hex/dec/oct values to check if they're equal to user input](https://stackoverflow.com/a/47193170/3422102) and [How do I limit the input of scanf to integers and floats(numbers in general)](https://stackoverflow.com/a/53727344/3422102) – David C. Rankin Mar 15 '21 at 23:33
  • Try typing `"10"` then TAB, then Enter. Note that the enter key usually makes `'\n'` with an ASCII value of 10. – chux - Reinstate Monica Mar 16 '21 at 01:34

1 Answers1

0

Finding problems and solving them

You have plenty of errors in the code that are listed below.

  1. The getchar(3) says:

    getchar() is equivalent to getc(stdin).

    The prototype of getc() is:

    int getc(FILE *stream);
    

    That is, the getchar() returns an integer (from unsigned char cast). Thus, we need to change the type from char to int to accept its return value correctly.

    Note that EOF is not a valid unsigned char. It expands to signed int -1.

  2. Never ignore the return value of the scanf(3). It returns the number of correctly passed arguments. In this case, to make the code reliable, we should put:

    if (scanf("%d", &b) != 1) {
      fprintf(stderr, "Value must be an integer.\n");
      return EXIT_FAILURE;
    }
    
  3. There is a semantic error in the condition:

    if (c >= 9 || c < 0)
          ^^____________ logically, 9 is a valid one digit number
                         so removing '=' from here makes more sense
    

    One notable thing is that the condition and the type of the comparator – both should be changed. See the next step.

  4. The fixed loop should look like:

    while ((c = getchar()) != EOF) {
      if (c == '\n') // Since c = getchar() can be '\n' too
        continue;    // so, better ignore
    
      if (c >= '0' && c <= '9') // Change the loop like this
        printf("Valid number %d %c.\n", c, c);
      else
        printf("Invalid number.\n");
    }
    

Sample test case output

1 
10    // --- Note: 10 are two chars for two getchars
Valid number 49 1.
Valid number 48 0.
3
Valid number 51 3.
9
Valid number 57 9.
- 
Invalid number.
a
Invalid number.
<
Invalid number.
.
Invalid number.
Rohan Bari
  • 6,523
  • 3
  • 9
  • 30
  • 1
    Right idea: use `int c`, Wrong reason: "Note that EOF is not a valid char! It expands to -1" --> -1 is a valid value for a _signed_ `char`. `int` needed to distinguish the 256 `unsgined char` values and `EOF`. – chux - Reinstate Monica Mar 16 '21 at 01:32