0

I practice a simple example to input operator in C: The code as here:

#include <stdio.h>
int main() {
    int a,b;
    char opera;
    printf("input 2 integer number ");
    scanf("%d %d",&a,&b);

    printf("\n input the operator: ");
    scanf("%c", &opera);

    switch (opera)
    {
    case '+':
        printf("result is %d \n", a+b);
        break; 
    default:
        break;
    }
}

Problem: Terminal will pass the input operator

input 2 integer number
4 5
input the operator:
PS D:\Quang\3. Study\C\Bai 2\.vscode>

But if I input operate first, it work:

#include <stdio.h>
int main() {
    int a,b;
    char opera;
    printf("\n input the operator: ");
    scanf("%c", &opera);
    printf("input 2 integer number");
    scanf("%d %d",&a,&b);
    switch (opera)
    {
    case '+':
        printf("result is %d \n",a+b);
        break; 
    default:
        break;
    }
}

Result:

input the operator: +
input 2 integer number 4 5
result is 9

Anyone has the same issue with VS Code?

Dmitry Kuzminov
  • 6,180
  • 6
  • 18
  • 40
Quang Tong
  • 19
  • 1
  • 1
  • 5
  • 3
    Try `scanf(" %c", &opera);` instead, then lookup [the docs](https://en.cppreference.com/w/c/io/fscanf) to see why, specifically the part about whitespace and newlines. – dxiv Jun 12 '20 at 03:22
  • 3
    Also, avoid using `scanf()` on potentially malformed input, like what the user might enter on the terminal. Read complete lines of input (`fgets`), then parse in-memory. If you *have* to use `scanf`, at least check the return value, to see that your variables actually got a value assigned (because otherwise you're risking undefined behavior). – DevSolar Jun 12 '20 at 03:26
  • 4
    It has nothing to do with your editor... – Shawn Jun 12 '20 at 03:28
  • 1
    I promise you that `scanf` works as documented. **Did you read [scanf(3)](https://man7.org/linux/man-pages/man3/scanf.3.html)?** It is unlikely that your C standard library `scanf` has important bugs, even if that does sometimes happen. Read [*How to debug small programs*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) and the [documentation of every standard C function](https://en.cppreference.com/w/c) you are using, and the documentation of your compiler (perhaps [GCC](http://gcc.gnu.org/)...) and debugger (e.g. [GDB](https://sourceware.org/gdb/current/onlinedocs/gdb/)) – Basile Starynkevitch Jun 12 '20 at 03:31
  • 1
    You could **read the C standard [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf). That document explains how `scanf` should behave.** You forgot to test the integer result of `scanf` – Basile Starynkevitch Jun 12 '20 at 03:41
  • @BasileStarynkevitch I would be cautious about promising that Microsoft versions of stdio work as documented – M.M Jun 12 '20 at 05:10

3 Answers3

0

Well after scanning the two integers, the stdin buffer is not empty a '\n' new line char is left there, so after reading one char to be the operator, you actually read that new line char, so you can fix that by making a custom flush function, that just reads the chars left in the stdin like this:

#include <stdio.h>

// make stdin buffer empty
void flush() {
  int c;
  while(1) {
    c = fgetc(stdin);
    if(c == EOF || c == '\n') break;
  }
}

int main() {
  int a, b;
  char opera;
  printf("input 2 integer number ");
  scanf("%d %d",&a,&b);
  flush();
  printf("input the operator: ");
  scanf("%c", &opera);

  // I have added other operators
  switch (opera) {
    case '+': printf("result is %d", a + b); break;
    case '-': printf("result is %d", a - b); break;
    case '/': printf("result is %d", a / b); break;
    case '*': printf("result is %d", a * b); break;
    case '%': printf("result is %d", a % b); break;
    default: printf("unknown operation");
  }
}

or simply just read the new line char with the scanf before reading the actual operator like this:

#include <stdio.h>

int main() {
  int a, b;
  char opera;
  printf("input 2 integer number ");
  scanf("%d %d",&a,&b);
  printf("input the operator: ");
  // read the new line char before reading the operator
  scanf(" %c", &opera);

  // I have added other operators
  switch(opera) {
    case '+': printf("result is %d", a + b); break;
    case '-': printf("result is %d", a - b); break;
    case '/': printf("result is %d", a / b); break;
    case '*': printf("result is %d", a * b); break;
    case '%': printf("result is %d", a % b); break;
    default: printf("unknown operation");
  }
}

Result:

input 2 integer number 4 5
input the operator: *
result is 20
Saadi Toumi Fouad
  • 2,779
  • 2
  • 5
  • 18
  • 1
    `scanf("\n%c", &opera);` is a bit misleading. the `\n` will match any sequence of whitespace characters. It is more idiomatic to write `scanf(" %c", &opera);` – chqrlie Jun 12 '20 at 08:20
0

Well that is because you enter 2 numbers at first...

input 2 integer number 4 5

at the end, you press enter key. So this '\n' character is stored in input buffer... When your next statement executes :

scanf("%c", &opera);

this input is fulfilled by '\n' already present in buffer. This causes skipping of input.

SOLUTION :-

Use the below statement.

scanf(" %c",&opera);        // Any extra spaces or newline will be discarded...

You wanna read this :-

C - FAQs

-1

There are two methods to solve the issue:

  1. Use fflush(stdin) just before the scanf(..., &opera) statement.
  2. If you don't want to follow the aforementioned step, just leave a whitespace before %c character of scanf(..., &opera), something like:

    scanf(" %c", &opera);
    
Rohan Bari
  • 7,482
  • 3
  • 14
  • 34