首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >计算错误,使用+而不是-

计算错误,使用+而不是-
EN

Stack Overflow用户
提问于 2019-09-10 05:41:11
回答 1查看 97关注 0票数 1

为了训练的原因,我想编写一个小计算器。为什么计算10-6 = 16而不是10-6 = 4?

我发现了一个错误:

代码语言:javascript
运行
复制
Assertion Failed!
Expression: calc("10-6") == 4 && "could not do substraction"

这是我的密码

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <ctype.h>

double calc(char * input);
double extract_first_integer(char * input);
double extract_last_integer(char * input);
char extract_operand(char * input);

int main()
{
   assert(calc("10-6") == 4 && "could not do substraction");

   return 0;
}

double calc(char * input){
   double num1 = extract_first_integer(input);
   double num2 = extract_last_integer(input);
   char operand = extract_operand(input);
   printf("operand is %c\n", operand);
   switch (operand)
   {
   case '-':
      printf("num1 - num2: %f\n", num1-num2);  // output: 16 instead of 4
      return num1 - num2;
      break;
   }
}

double extract_first_integer(char * input){
   char *str = input, *p = str;
   double val;
   while (*p) { // While there are more characters to process...
      if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
         // Found a number
         val = strtol(p, &p, 10); // Read number
         return val;
      } else {
         // Otherwise, move on to the next character.
         p++;
      }
   }
}

double extract_last_integer(char * input){
   char *str = input, *p = str;
   double val;
   while (*p) { // While there are more characters to process...
      if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
         // Found a number
         val = strtol(p, &p, 10); // Read number
      } else {
         // Otherwise, move on to the next character.
         p++;
      }
   }
   return val;
}

char extract_operand(char * input){
   if (strstr(input, "-")) return '-';
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-10 05:46:22

extract_last_integer()

代码语言:javascript
运行
复制
while (*p) { // While there are more characters to process...
  if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
     // Found a number
     val = strtol(p, &p, 10); // Read number
  } else {
     // Otherwise, move on to the next character.
     p++;
  }
}

这会增加p,直到它达到第一个数字或-/+后面的一个数字为止。所以它将匹配,第一个,,,number。但是,请注意,您是,而不是像extract_first_integer()中的早期return val;那样中断循环。当您继续匹配下一个数字时,"10-6"中的"10-6"将被匹配。10 - (-6)显然是16岁

您还可能有未定义的行为

  • 传递指向strtol的相同指针。变量str未使用,应该在str_end参数中传递。
  • const char* ("10-6")传递给需要char*的函数

3个extract...函数的性能也不是很好,因为它们都需要从输入字符串开始迭代。要解决这个问题,您应该返回当前数字的位置并从该位置启动下一个函数。这样,您可以使用相同的函数来解析整数,而不是编写两个整数。

再说,你的名字倒过来了。这两个整数称为https://en.wikipedia.org/wiki/Operand,连接两个操作数的东西称为https://en.wikipedia.org/wiki/Operation_(mathematics)),而不是操作数。为什么只读取整数时返回double

所以,在解决了这些问题之后,我们将

代码语言:javascript
运行
复制
int extract_operand(char * input, size_t *lastChar);
char extract_operator(char * input, size_t *lastChar);

size_t lastPos;
int num1 = extract_operand(input, &lastPos);
char operand = extract_operator(input + lastPos, &lastPos);
int num2  = extract_operand(input + lastPos, &lastPos);

但这只适用于二元算子和2个操作数这样的简单情况。对于更复杂的情况,需要一个令牌器将输入流拆分成一个令牌列表

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57864631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档