我试图在C中创建一个计算器。我在我的eval函数中的(char * String)参数是正确的,但我并不感兴趣。我真的明白为什么或如何正确使用它。我的eval函数将以后缀表示法输入数学表达式。所以这是我的代码到目前为止,基本上我试图接受一个字符串,将所有数字推入一个字符串堆栈然后如果找到一个运算符,弹出两个'字符串'关闭字符串堆栈,将这些字符串转换为整数(这是我不确定如何做的另一件事),进行计算,将结果推送到int堆栈。在搜索完所有输入之后,遍历int堆栈并添加所有的int。这是我的代码:(忽略包括)/ *
int eval(char* String); //implicit declarations
int bourneLongPush(int);
char* bournePop(void);
int bournePush(char *string);
int bourneLongPop(void);
int bourneGetLongStackSize(void);
int eval(char* String)
{
int result = 0;
int index = 0;
int arg1;
int arg2;
char* endptr;
while(String[index] != '\0'){ //while our String pointer is not equal to null,
if(strtoimax(String, &endptr, 10) == NULL){ //if the character isn't a number,
switch(String[index]){ //switch on the operator
case "+":
arg2 = bournePop();
arg1 = bournePop();//*** how do I change char*'s to ints?
bourneLongPush(arg2+arg1);
break;
case "-":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2-arg1);
break;
case "/":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2/arg1);
break;
case "*":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2*arg1);
break;
case ">":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2>>arg1);
break;
case "<":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2<<arg1);
break;
case "^":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(pow(arg2, arg1));
break;
case "|":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2|arg1);
break;
case "&":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2&arg1);
break;
case "%":
arg2 = bournePop();
arg1 = bournePop();
bourneLongPush(arg2%arg1);
break;
default:
break;
}
else{ //a number was found
int check = bournePush(String[index]);//push the number into string stack
if(check == 1)
{
//error in push due to size
}
}
index++;
}
}
//Our input was read in as null so no more input needs to be read
for(int j = 0; j<(int)bourneGetLongStackSize; j++)
{
int num = bourneLongPop();
result += num;
}
return result;
}
答案 0 :(得分:1)
所以,我建议不要将所有字符都推入堆栈然后将它们转换为整数并应用运算符,为什么我们不将它们转换为整数然后将它们推入堆栈然后应用运算符。
因此,循环中的else
条件看起来像这样::
int num = 0;
while() {
if(the character isn't a number) { //I do not exactly understand the condition you used here, but I hope you have got it figured
bournePush(num);
num = 0;
switch(String[index]) {
...
...
//remains same
}
}
else {
convertToNum(num, string[index]);
}
}
在这里,我使用num
存储当前字符串中的数字值,因此,如果我在字符串中遇到123
,我将int 123
存储在num
中使用convertToNum
函数,所以当我点击运算符时,我只需将堆栈中的完整num
推入并重新初始化为0
,这样我就可以用它来存储下一个数字。 / p>
这就是convertToNum
看起来像::
void convertToNum(int &num, char digit) {
int numDigit = digit - '0';
num = num*10 + numDigit;
}
那么这将回答你关于如何将字符转换为整数的问题。在这里,我通过引用传递num
,以便在converToNum
中看到我在main
中所做的任何更改。然后在numDigit
中,我从char
中减去0
digit
,这将从char 0
中减去char digit
的ASCII值,并为我们提供值由该字符表示的整数。然后我用10
做一个简单的乘法并加上下一个数字,只是简单的数学。
此外,这极大地简化了bournePop
和borneLongPop
函数,因为现在你的堆栈只是整数,所以你不需要分离函数,现在你只需要弹出一个值堆栈并将其与switch
中的运算符一起使用。
我希望这有帮助!
编辑::
我假设你的postfix字符串之间有空格来表示单独的数字,所以你可能实际上有一个像这样的字符串::
123 456 +
所以,上面的代码实际上会失败,因为在456
之后它会遇到空间,它会进入if
条件并将456
推入堆栈然后它会命中+
它会将0
推入堆叠,然后在+
上应用0 and 456
这是错误的,因此我们将bournePush
num
只有当我们遇到空间时才会堆叠所以你的最终代码应该是这样的::
int num = 0;
while() {
if(the character isn't a number) { //I do not exactly understand the condition you used here, but I hope you have got it figured
if(String[index] == ' ') {
bournePush(num);
num = 0;
} else {
switch(String[index]) {
...
...
//remains same
}
}
}
else {
convertToNum(num, string[index]);
}
}
此外,我并不认为您的switch
会有效,因为当您撰写switch(String[index])
时,您在撰写{{1}时为switch
定义了char
你相信,你将case条件定义为一个字符串,它会产生编译错误。因此,您的所有case "+"
都应该像case
一样进行更改,这样就可以了。
此外,检查字符是否为数字的更简单方法是::
case '+'
此检查int checkNum(char a) {
if(a >= '0' && a <= '9')
return 0;
return 1;
}
是否在a
和0
之间,并返回9
(false)和0
(true),否则,只是建议!
答案 1 :(得分:1)
1)if(strtoimax(String, &endptr, 10) == NULL){
不是一个很好的测试,看看转换是否有效。
intmax_t value = strtoimax(String, &endptr, 10);
if (endptr != String) {
// endptr now points to the next part of the string to parse
ConversionWorked(value);
} else
ConversionFailed();
}
代码可以清除errno
以检测溢出
errno = 0;
intmax_t = value = strtoimax(String, &endptr, 10);
if (endptr != String) {
if (errno) ConversionOverflowed(value)
else ConversionWorked(value);
} else
ConversionFailed();
}
2)错误switch()
用法
switch(String[index]) {
// case "+":
case '+': // String[index] is a `char`, not a string
3)可能还有其他问题,例如bournePush()
- 但需要查看未解决的代码才能解决..