为了训练的原因,我想编写一个小计算器。为什么计算10-6 = 16而不是10-6 = 4?
我发现了一个错误:
Assertion Failed!
Expression: calc("10-6") == 4 && "could not do substraction"
这是我的密码
#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 '-';
}
发布于 2019-09-10 05:46:22
在extract_last_integer()
中
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
?
所以,在解决了这些问题之后,我们将
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);
https://stackoverflow.com/questions/57864631
复制相似问题