【问题标题】:A Calculator program in CC语言的计算器程序
【发布时间】:2013-12-03 11:03:03
【问题描述】:

我正在尝试用 C 编写一个计算器程序。

输入必须完全是这种形式:

a oper b

其中 a、b 是 double 类型的数字,oper 是这些字符 +、-、*、/ 的数字。

代码:

int main()
{
   char oper;
   double a, b;

   printf("What do you want to calculate?\n");
   if (scanf("%lf %1[-+/*] %lf", &a, &oper, &b) != 3)
        printf("Error. Invalid input.\n");
    else {

   switch(oper)
   {
    case '+':
        printf("%f+%f=%.2f",a,b,a+b);
        break;
    case '-':
        printf("%f-%f=%.2f",a,b,a-b);
        break;
    case '*':
        printf("%f*%f=%.2f",a,b,a*b);
        break;
    case '/':
        if(b != 0)
        {
                    printf("%f/%f=%.2f",a,b,a/b);
            break;
        }
        else
        {
            printf("Error! You can not divide by 0.");
            break;
        }
    default:
        printf("Error! Invalid operator.");
        break;
   }}
   return 0;
}

问题:

当用户输入例如这个输入时:

123

程序将冻结。

同时当用户输入这些输入时:

123 5
123 ab
Hello

我们的程序将打印出来

ERROR. Invalid input.

我真的需要你的帮助。请您修复我的代码,以便我们输入此输入,例如:

123

我们的程序将打印出来

ERROR. Invalid input.

谢谢

【问题讨论】:

  • 你也有char oper; ... scanf("%lf %1[-+/*] %lf", &a, &oper, &b)的问题。更改为char oper[2]scanf("%lf %1[-+/*] %lf", &a, oper, &b)

标签: c calculator


【解决方案1】:

fgets开头:

char buffer[256];
printf("What do you want to calculate?\n");
fgets(buffer, 256, stdin);
if (sscanf(buffer, "%lf %1[-+/*] %lf", &a, &oper, &b) != 3)
    printf("Error. Invalid input.\n");
// .. rest of the code

【讨论】:

  • 建议对oper 进行更改,因为%1[-+/*] 需要一个字符串。
【解决方案2】:

您的程序在输入123 时“冻结”,因为当用户按下回车时,scanf 尚未完成读取;它期望运算符和其他操作数跟随。您可以在后续行中输入这些内容。这是因为scanf 格式化程序中的任何空格都可以代表输入中任何数量和类型的空格,即123\n+\n\t 456 是有效的并且产生与输入123+456 相同的结果。

我建议使用fgets 一次将一行读入缓冲区,然后从那里解析它,例如使用sscanf。如果您只想坚持使用scanf,可以使格式不允许换行符分隔符,但是您必须在运算符和操作数之间有空格:

if (scanf("%lf%*[ \t]%1[-+/*]%*[ \t]%lf", &a, &oper, &b) != 3)

edit:另外,正如@chux 所指出的,将%1[-+/*] 的结果存储在char oper 中是不正确的,因为%[] 格式化程序会生成一个字符串,这意味着必须为终止 NUL 字符留出空间。将类型更改为char oper[2] 或将格式更改为%c

【讨论】:

  • “必须在运算符和操作数之间有空格”不太正确。 "%lf"" %lf" 行为相同。两者都会很好地消耗\n,然后继续扫描double
  • @chux %*[ \t] 将不匹配空字符串,并导致scanf123\n 输入的OP 问题案例中返回。
  • 我看到了我的方式的错误。忘记%[] 不匹配空字符串。
  • 在任何情况下,fgets 解决方案更健壮和更可取,scanf 解决方案仍然有其他有问题的输入,例如123 + \n
【解决方案3】:

在我的测试中,当您输入“123”时,程序并没有冻结,它只是在等待下一行的更多输入。如果你想强制它从一行中获取所有输入,我知道它如何将字符串读入内存,然后使用 sscanf() 扫描字符串的最简单方法。

所以程序的顶部看起来像这样:

int main()
{
    char line[100] ;
    char oper[4];
    double a, b;

    printf("What do you want to calculate?\n");
    if ( ! fgets(line, sizeof(line), stdin))
        { printf("No input.\n") ;  exit( 1) ; }
    if (sscanf(line, "%lf %1[-+/*] %lf\n", &a, &oper, &b) != 3)
        printf("Error. Invalid input.\n");
    else {
        switch (* oper) {

此外,您可能希望在输出后添加换行符。

【讨论】:

  • 建议对oper 进行更改,因为%1[-+/*] 需要一个字符串。
  • 很好的电话@chux。它以前工作过,但可能只是因为数据类型填充而安全。出于各种原因,我不倾向于使用 scanf(),包括缓冲区溢出的可能性。
【解决方案4】:
#include<Stdio.h>
int main()
{
 double a,b;
 char operator;
 puts("Please enter your two operands");
 printf("operand no 1 = ");
 scanf("%f",&a);
 printf("operand no 2 = ");
 scanf("%f",&b);
 puts("Now choose what do you want to calculate");
 printf("+ - * / which one : ");
 scanf("%c",operator);
 if(operator=='+')
   printf("ans = %f ",a+b);
 else if(operator=='-')
   printf("ans = %f ",a-b);
 elseif(operator=='*')
   printf("ans = %f ",a*b);
 else if(operator=='/')
   printf("ans = %f ",a/b);
 puts("thank you !");
return 0;
}

【讨论】:

  • 适合初学者的简单计算器
猜你喜欢
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
  • 1970-01-01
  • 2023-04-09
  • 2014-05-22
相关资源
最近更新 更多