如何在 C 中使用 char* 循环遍历字符?
How do I loop through characters with char*'s in C?
我正在尝试用 C 语言创建一个计算器。我确信我的 eval 函数中的 (char* String) 参数是正确的,但我没有真正理解为什么或如何正确使用它。我的 eval 函数将以后缀表示法给出数学表达式的输入。到目前为止,这是我的代码,本质上我是在尝试接收一个字符串,将所有数字压入字符串堆栈,然后如果找到运算符,则从字符串堆栈中弹出两个 'strings',将这些字符串转换为整数(这是我不确定如何做的另一件事),进行计算,将结果推入 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] != '[=10=]'){ //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;
}
所以,我建议与其将所有字符压入堆栈,然后将它们转换为整数并应用运算符,不如在将它们压入堆栈之前将它们转换为整数,然后应用运算符。
因此,循环中的 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
压入堆栈并将 re-initialize 压入 0
以便我可以使用它来存储下一个号码。
这就是 convertToNum
的样子 ::
void convertToNum(int &num, char digit) {
int numDigit = digit - '0';
num = num*10 + numDigit;
}
那么这将回答您关于如何将字符转换为整数的问题。在这里,我通过引用传递 num
,这样我在 converToNum
中所做的任何更改也会在 main
中看到。然后在 numDigit
中我从 digit
中减去 char
0
这将从 char digit
中减去 char 0
的 ASCII 值并给我们值该字符表示的整数。然后我用 10
做一个简单的乘法并添加下一个数字,只是简单的数学运算。
此外,这大大简化了 bournePop
和 borneLongPop
函数,因为现在你的堆栈只是整数,所以你不需要分离函数,现在你只需弹出一个堆栈中的值并将其与 switch
.
中的运算符一起使用
希望对您有所帮助!
编辑::
我假设你的后缀字符串之间有 spaces 来表示单独的数字,所以你实际上可能有这样的字符串 ::
123 456 +
所以,上面的代码实际上会失败,因为在 456
之后它会遇到 space,它将进入 if
条件并将 456
压入堆栈然后当它命中 +
时,它会将 0
压入堆栈,然后在 0 and 456
上应用 +
这是错误的,所以我们应该 bournePush
num
只有在遇到space的时候才会在栈中。所以你的最终代码应该是这样的::
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])
时,你已经为 char
定义了 switch
当你写 case "+"
我相信你将 case 条件定义为一个会产生编译错误的字符串。所以,你所有的case
都应该改成这样case '+'
,这样就可以了。
此外,一种更简单的检查字符是否为数字的方法是这样::
int checkNum(char a) {
if(a >= '0' && a <= '9')
return 0;
return 1;
}
这会检查 a
是否在 0
和 9
和 returns 之间 0
(false) 和 1
(true) 否则, 只是建议!
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()
- 但需要查看未发布的代码才能解决..
我正在尝试用 C 语言创建一个计算器。我确信我的 eval 函数中的 (char* String) 参数是正确的,但我没有真正理解为什么或如何正确使用它。我的 eval 函数将以后缀表示法给出数学表达式的输入。到目前为止,这是我的代码,本质上我是在尝试接收一个字符串,将所有数字压入字符串堆栈,然后如果找到运算符,则从字符串堆栈中弹出两个 'strings',将这些字符串转换为整数(这是我不确定如何做的另一件事),进行计算,将结果推入 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] != '[=10=]'){ //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;
}
所以,我建议与其将所有字符压入堆栈,然后将它们转换为整数并应用运算符,不如在将它们压入堆栈之前将它们转换为整数,然后应用运算符。
因此,循环中的 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
压入堆栈并将 re-initialize 压入 0
以便我可以使用它来存储下一个号码。
这就是 convertToNum
的样子 ::
void convertToNum(int &num, char digit) {
int numDigit = digit - '0';
num = num*10 + numDigit;
}
那么这将回答您关于如何将字符转换为整数的问题。在这里,我通过引用传递 num
,这样我在 converToNum
中所做的任何更改也会在 main
中看到。然后在 numDigit
中我从 digit
中减去 char
0
这将从 char digit
中减去 char 0
的 ASCII 值并给我们值该字符表示的整数。然后我用 10
做一个简单的乘法并添加下一个数字,只是简单的数学运算。
此外,这大大简化了 bournePop
和 borneLongPop
函数,因为现在你的堆栈只是整数,所以你不需要分离函数,现在你只需弹出一个堆栈中的值并将其与 switch
.
希望对您有所帮助!
编辑::
我假设你的后缀字符串之间有 spaces 来表示单独的数字,所以你实际上可能有这样的字符串 ::
123 456 +
所以,上面的代码实际上会失败,因为在 456
之后它会遇到 space,它将进入 if
条件并将 456
压入堆栈然后当它命中 +
时,它会将 0
压入堆栈,然后在 0 and 456
上应用 +
这是错误的,所以我们应该 bournePush
num
只有在遇到space的时候才会在栈中。所以你的最终代码应该是这样的::
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])
时,你已经为 char
定义了 switch
当你写 case "+"
我相信你将 case 条件定义为一个会产生编译错误的字符串。所以,你所有的case
都应该改成这样case '+'
,这样就可以了。
此外,一种更简单的检查字符是否为数字的方法是这样::
int checkNum(char a) {
if(a >= '0' && a <= '9')
return 0;
return 1;
}
这会检查 a
是否在 0
和 9
和 returns 之间 0
(false) 和 1
(true) 否则, 只是建议!
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()
- 但需要查看未发布的代码才能解决..