-2

I'm making a simple calculator in C and I want the program to show the message "Enter an operator!" when the user enters something that isn't an operator, enter, space or tab. but if the user enters a number like 123 the message is shown 3 times instead of once. how can I fix this?

char op;
printf("please choose an operator (+,-,*,/): ");
while (op!='+' && op!='*' &&op!='-' &&op!='/' )
    {
    if (op!='\n'&& op!= '\t'&& op!=' ')
    printf ("Enter an operator!\n");
    scanf ("%c",&op);
    }
  • Use `getchar()` instead. – Robert Harvey Jun 23 '22 at 11:32
  • 1
    Also, you need to get your first char before you enter the `while` loop. Otherwise, `op` is unassigned, and undefined behavior results. – Robert Harvey Jun 23 '22 at 11:33
  • If the user types "`ab`" do you want one error message or two? If the user types "`..`" do you want one error message or two? If the user types "`!$`" do you want one error message or two? – Steve Summit Jun 23 '22 at 11:56
  • It might be simpler overall to read a *string* (using `%s`) rather than a single character. Or perhaps an entire *line* of text (using `fgets`). Then call `strlen` to see if it's one character long. (Also [strip the newline](https://stackoverflow.com/questions/2693776) if you used `fgets`.) – Steve Summit Jun 23 '22 at 11:59
  • Also, what if the user types "`++`"? Should that get an error message, and if so, how many? – Steve Summit Jun 23 '22 at 12:04
  • When you get to the bottom of it, this ends up being a question about [lexical analysis](https://en.wikipedia.org/wiki/Lexical_analysis). (And a search for a truly proper answer would reveal that `scanf` is simply not the right tool for the job.) – Steve Summit Jun 23 '22 at 12:15

3 Answers3

0

A scan set could be used %1[+-/*] will scan one character in the set of operators.
If the character is not in the set, scanf will return 0. Clean the input stream and try again.

#include <stdio.h>
#include <stdlib.h>

int main ( void) {
    char op[2] = "";
    int result = 1;

    printf ("Enter an operator!\n");
    do {
        if ( result != 1) {
            printf ("Enter an operator!\n");
        }
        result = scanf ( "%1[+-/*]", op);
        if ( result == EOF) {
            fprintf ( stderr, "EOF\n");
            return 1;
        }
        int clean = 0;
        while ( ( clean = fgetc ( stdin)) != '\n') { // clean input stream
            if ( clean == EOF) {
                fprintf ( stderr, "EOF\n");
                return 1;
            }
        }
    } while ( result != 1);

    printf ( "operator %s\n", op);

    return 0;
}
xing
  • 2,125
  • 2
  • 14
  • 10
0

For starters use the format string " %c" to enter a character. Pay attention to the leading space in the format string. It allows to skip white space characters as for example the new line character '\n'.

Pay attention to that you are using an uninitialized variable op in the condition of the while loop that results in undefined behavior.

char op;
printf("please choose an operator (+,-,*,/): ");
while (op!='+' && op!='*' &&op!='-' &&op!='/' )
//...

A simplified approach can look the following way

#include <stdio.h>
#include <string.h>

//...

char op;
printf("please choose an operator (+,-,*,/): ");
const char *operations = "+*-/";

while ( 1 )
{
    int result = scanf( " %c", &op );

    if ( result == 1 && strchr( operations, op ) != NULL )
    {
        break;
    }

    if ( result == 1 )
    {
        scanf( "%*[^\n]" );
    } 

    printf ("Enter an operator!\n");
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
-2

1st thing first. 1 rule I learned is that a function only do 1 thing. In your case, scanf("%c", &op) is being called multiple times. Put the scanf() between the while() loop and printf() and retry. You can use a do{...}while; loop too.

MimiValsi
  • 11
  • 2