当我在 C 中输入操作(+、-、*、/ 等)时,scanf 失败

scanf fails when I type in operations (+,-,*,/ etc) in C

我正在用 C 构建一个计算器,遇到了有关字符 scanf 的问题。我已经定义了一个名为 operationValue 的“字符串”,但是当我尝试执行 scanf 函数(我在它旁边有注释的函数)时,它会立即打印出一个无效字符,而不是我输入的操作。我需要字符串而不仅仅是一个字符,因为我有其他的幂和根操作,但即使我输入它们也不起作用。当我完成代码时,它会打印“无效操作”。

抱歉,如果这不是堆栈溢出中的常规内容,但这是我第一次来这里。如果代码太长什么的,请帮我编辑一下,下次我就学会不这样了。

#include <stdio.h>

void theOperation(double num1, char operationValue, double num2)
{
    if(operationValue == "+")
    {
        printf("%lf\n", num1 + num2);
    } else if(operationValue == "-")
    {
        printf("%lf\n", num1 - num2);

    } else if(operationValue == "*")
    {
        printf("%lf\n", num1 * num2);

    } else if(operationValue == "/")
    {
        printf("%lf\n", num1 / num2);
    } else if(operationValue == "pow")
    {
        printf("%lf\n", pow(num1, num2));
    } else if(operationValue == "root")
    {
        printf("%lf\n", pow(num1, (1/num2)));
    } else
    {
        printf("Not valid operation");
    }
}


int main()
{
    double num1, num2;
    char operationValue[10];

    printf("This is a calculator.\n");
    printf("Enter first number: ");
    scanf("%lf", &num1);
    printf("%lf\n", num1);

    printf("Enter operation: ");
    scanf(" %s", &operationValue);
    printf("%c\n", operationValue);     // This line fails when I type in any operation I define: '+', '-', '*', '/' 'pow' 'root'

    printf("Enter second number: ");
    scanf("%lf", &num2);
    printf("%lf\n", num2);

    theOperation(num1, operationValue, num2);

    return 0;
}

通过添加类型并确保参数正确传递来修复代码并不难:

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

void theOperation(double num1, char operationValue, double num2)
{
    switch (operationValue) {
        case '+':
            printf("%lf\n", num1 + num2);
            break;
        case '-':
            printf("%lf\n", num1 - num2);
            break;
        case '/':
            printf("%lf\n", num1 / num2);
            break;
        case '*':
            printf("%lf\n", num1 * num2);
            break;
        default:
            printf("Not valid operation");
    }
}

int main()
{
    double num1, num2;
    char operationValue;

    printf("This is a calculator.\n");
    printf("Enter first number: ");
    scanf("%lf", &num1);
    printf("%lf\n", num1);

    printf("Enter operation: ");
    scanf(" %c", &operationValue);
    printf("%c\n", operationValue);

    printf("Enter second number: ");
    scanf("%lf", &num2);
    printf("%lf\n", num2);

    theOperation(num1, operationValue, num2);

    return 0;
}

代码有几个缺陷:

  1. 给出的函数签名:

    int theOperation(num1, operationValue, num2)
    

    不正确。您必须在标识符旁边定义数据类型。

  2. 函数returnsint没用到

  3. 一个变量char[10]传递给一个接受char的函数,这显然会产生意想不到的结果。

  4. 如果要使用pow()sqrt()floor()等数学函数,必须定义头文件math.h .它们在 stdio.h 中不可用(仅包含 I/O 操作函数和子程序)。


代码重新定义:

#include <stdio.h>

// return type set to: void, datatypes defined for function parameters
void theOperation(double num1, char operationValue, double num2)
{
    double result = 0;

    // calculating the results based on operations
    switch (operationValue) {
        case '+': result = num1 + num2; break;
        case '-': result = num1 - num2; break;
        case '*': result = num1 * num2; break;
        case '/': result = num1 / num2; break;

        default:
            printf("No such operation found.\n");
            break;
    }

    printf("Result: %lf\n", result);
}


int main(void)
{
    double num1, num2;
    char operationValue;

    printf("This is a calculator.\n");
    printf("Enter first and second number: ");
    scanf("%lf %lf", &num1, &num2);
    printf("%lf %lf\n", num1, num2);

    printf("Enter operation: ");
    scanf(" %c", &operationValue);
    printf("%c\n", operationValue);

    // the operation execution
    theOperation(num1, operationValue, num2);

    return 0;
}

解释很简单。

scanf() 从用户那里获取必要的数据,然后将参数传递给函数 theOperation() 及其适当的参数。此后,switch 语句尝试匹配 case 语句中给出的表达式与 operationValue.

相同

当它确实找到一个时,它只是计算表达式并打印结果。

注:如果你只是想比较单个字母,如+-*/,等那么你仍然不需要使用字符数组来使用 strcmp() 或任何东西来比较它们。


它给出以下输出:

This is a calculator.
Enter first and second number: 10 50
10.000000 50.000000
Enter operation: -
-
Result: -40.000000
  • %c in scanf() 是读一个字符。您应该使用 %(max length)s 来读取字符串(不包含空白字符)。 (max length) 应该是缓冲区大小减一(用于终止空字符)。另请注意 %(max length)s 将占用 char*,因此您不应将 & 放在数组之前。
  • %c in printf() 是打印一个字符。您应该使用 %s 来打印字符串。
#include <stdio.h>

int main()
{
    double num1, num2;
    char operationValue[10];
    
    printf("This is a calculator.\n");
    printf("Enter first number: ");
    scanf("%lf", &num1);
    printf("%lf\n", num1);
    
    printf("Enter operation: ");
    scanf(" %9s", operationValue);
    printf("%s\n", operationValue);
    
    printf("Enter second number: ");
    scanf("%lf", &num2);
    printf("%lf\n", num2);


    return 0;
}

使用“%s”读取和打印运算符:

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

void theOperation(double num1, char* operationValue, double num2)
{
    if(strcmp(operationValue, "+") == 0)
    {
        printf("%lf\n", num1 + num2);
    } else if(strcmp(operationValue, "-") == 0)
    {
        printf("%lf\n", num1 - num2);

    } else if(strcmp(operationValue,"*") == 0)
    {
        printf("%lf\n", num1 * num2);

    } else if(strcmp(operationValue,"/") == 0)
    {
        printf("%lf\n", num1 / num2);
    } else if(strcmp(operationValue,"pow") == 0)
    {
        printf("%lf\n", pow(num1, num2));
    } else if(strcmp(operationValue, "root") == 0)
    {
        printf("%lf\n", pow(num1, (1/num2)));
    } else
    {
        printf("Not valid operation");
    }
}


int main()
{
    double num1, num2;
    char operationValue[10];

    printf("This is a calculator.\n");
    printf("Enter first number: ");
    scanf("%lf", &num1);
    printf("%lf\n", num1);

    printf("Enter operation: ");
    scanf(" %9s", &operationValue);
    printf("%c\n", operationValue);

    printf("Enter second number: ");
    scanf("%lf", &num2);
    printf("%lf\n", num2);

    theOperation(num1, operationValue, num2);

    return 0;
}

Scanf() 文档:https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm

-- 编辑 --

我已将代码更新为可用代码。

我还更新了 scanf() 以读取像@M 这样的运算符。 Nejat Aydin 评论防止缓冲区溢出

我修复了函数参数、字符串与字符和错误的 scanf 格式字符,将您的所有操作(包括“pow”和“root”)与 switch():

相结合
#include <stdio.h>
#include <math.h>
#include <string.h>

void theOperation(double num1, const char *operationValue, double num2)
{
  switch(*operationValue) {
    case '+': printf("%lf\n", num1 + num2); break;
    case '-': printf("%lf\n", num1 - num2); break;
    case '*': printf("%lf\n", num1 * num2); break;
    case '/': printf("%lf\n", num1 / num2); break;
    default: {
      if(!strcmp(operationValue, "pow")) {
        printf("%lf\n", pow(num1, num2));
      } else if(!strcmp(operationValue, "root")) {
        printf("%lf\n", pow(num1, (1/num2)));
      } else printf("Not valid operation\n");
      break;
    }
  }
}

int main()
{
  double num1, num2;
  char operationValue[10];
  
  printf("This is a calculator.\n");
  printf("Enter first number: ");
  scanf("%lf", &num1);
  printf("%lf\n", num1);
  
  printf("Enter operation: ");
  scanf("%9s", operationValue);
  printf("operation entered: %s\n", operationValue);
  
  printf("Enter second number: ");
  scanf("%lf", &num2);
  printf("%lf\n", num2);

  theOperation(num1, operationValue, num2);

  return 0;
}

带有“power”的输出示例:

$ gcc -Wall -o calc calc.c ;./calc 
This is a calculator.
Enter first number: 2
2.000000
Enter operation: pow
operation entered: pow
Enter second number: 3
3.000000
8.000000

这是重要的一行:

scanf("%9s", operationValue);

(读取最多 9 个字符的字符串。)