嗨,我完全迷上了这个基本的计算器。它几乎可以完美运行,但是当我尝试输入“ 5/5 + 9 * 2”时,堆栈中出了点问题。当应该将5/5中的1加到最后一个循环的18中时,它似乎消失了。发生像2 * 2-9/2这样的模拟输入。只需要帮助找到这个奇怪的错误,我就花了很多小时试图找出运气!谢谢!
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <limits.h>
#include <curses.h>
#include<ctype.h>
struct StackNode
{
char* data;
struct StackNode* next;
};
struct StackNode* newNode(char* data)
{
struct StackNode* stackNode =
(struct StackNode*) malloc(sizeof(struct StackNode));
stackNode->data = data;
stackNode->next = NULL;
return stackNode;
}
int isEmpty(struct StackNode *root)
{
return !root;
}
void push(struct StackNode** root, char* data)
{
struct StackNode* stackNode = newNode(data);
stackNode->next = *root;
*root = stackNode;
printf("%s pushed to stack\n", data);
}
char* pop(struct StackNode** root)
{
if (isEmpty(*root))
return NULL;
struct StackNode* temp = *root;
*root = (*root)->next;
char* popped = temp->data;
free(temp);
printf("Popped: %s\n", popped);
return popped;
}
char* peek(struct StackNode* root)
{
if (isEmpty(root))
return NULL;
return root->data;
}
char buffer[64];
char *ca = &buffer[0];
size_t size = 64;
int bufferIndex;
int first = 0;
int isWhiteSpace (char c) {
if ((c == ' ') || (c == '\t') || (c == '\r')) {
return 1;
}
else {
return 0;
}
}
char* getToken() {
char* token = malloc(64);
int i = 0;
while ((isWhiteSpace(buffer[bufferIndex])) && bufferIndex < strlen(buffer)-1) {
bufferIndex++;
}
while (bufferIndex < strlen(buffer)-1) {
int num = isWhiteSpace(buffer[bufferIndex]);
if (num == 0) {
token[i] = buffer[bufferIndex];
i++;
bufferIndex++;
//printf("%s\n", token);
}
else {
bufferIndex++;
break;
}
}
token[i] = '\0';
first++;
return token;
}
int main() {
while (1) {
char* token = "test";
char* postFix = "test";
char* hold = malloc(64);
postFix = malloc(64);
int total = 0;
int pres1 = 0;
int pres2 = 0;
struct StackNode* root = NULL;
printf("Enter line: ");
getline(&ca,&size,stdin);
bufferIndex = 0;
if ((strcmp(token, "quit") == 0)) {
token = getToken();
if (strcmp(token, "") == 0) {
break;
}
else {
printf("Too many arguments. Try again.\n");
}
}
else {
while (strcmp(token, "") != 0) {
token = getToken();
//printf("%s\n", token);
//printf("Top of stack: %s\n", peek(root));
if (isdigit(*token) == 1) {
strcat(postFix, token);
strcat(postFix, " ");
printf("%s\n", postFix);
}
else if (peek(root) == NULL) {
push(&root, token);
}
else {
printf("Peek: %s\n", peek(root));
if (strcmp(token, "*") == 0) {
pres1 = 2;
}
else if (strcmp(token, "/") == 0) {
pres1 = 2;
}
else if (strcmp(token, "-") == 0) {
pres1 = 1;
}
else if (strcmp(token, "+") == 0) {
pres1 = 1;
}
else {
pres1 = 0;
}
if (strcmp(peek(root), "*") == 0) {
pres2 = 2;
}
else if (strcmp(peek(root), "/") == 0) {
pres2 = 2;
}
else if (strcmp(peek(root), "-") == 0) {
pres2 = 1;
}
else if (strcmp(peek(root), "+") == 0) {
pres2 = 1;
}
while((peek(root) != NULL) && (pres2 > pres1)) {
strcat(postFix, peek(root));
strcat(postFix, " ");
pop(&root);
printf("Postfix: %s\n", postFix);
}
push(&root, token);
}
}
do {
//printf("Peek in DO/WHILE: %s\n", peek(root));
strcat(postFix, peek(root));
strcat(postFix, " ");
pop(&root);
} while ((peek(root) != NULL));
printf("Postfix: %s\n", postFix);
//ca = NULL;
token = "1";
bufferIndex = 0;
for (int i = 0; i < strlen(postFix) + 1; i++) {
buffer[i] = postFix[i];
}
//size = strlen(postFix)+1;
//printf("TOKEN: %s\n", token);
while (strcmp(token, "") != 0) {
token = getToken();
if (isdigit(*token) == 1) {
//printf("--Token: %s\n", token);
push(&root, token);
}
else {
int operand1;
//operand1 = malloc(64);
int operand2;
//total = malloc(64);
printf("Peek: %s\n", peek(root));
operand2 = atoi(peek(root));
pop(&root);
printf("Operand2: %d\n", operand2);
if (strcmp(token, "") != 0) {
printf("Peek: %s\n", peek(root));
operand1 = atoi(peek(root));
pop(&root);
printf("Operand1: %d\n", operand1);
printf("Token: %s\n", token);
if (strcmp(token, "+") == 0) {
total = operand1 + operand2;
}
else if (strcmp(token, "/") == 0) {
total = operand1 / operand2;
}
else if (strcmp(token, "-") == 0) {
total = operand1 - operand2;
}
else if (strcmp(token, "*") == 0) {
total = operand1 * operand2;
}
sprintf(hold,"%d",total);
//printf("Peek: %s\n", peek(root));
push(&root, hold);
//pop(&root);
printf("Total: %d\n", total);
}
else {
//printf("Peek: %s\n", peek(root));
break;
}
}
}
}
printf("Total: %d\n", total);
}
return 0;
}
我应该/将其作为作业的参考:http://condor.depaul.edu/ichu/csc415/notes/notes9/Infix.htm
答案 0 :(得分:1)
代替:
if (isdigit(*token) == 1) {
使用:
if (isdigit((unsigned char)*token)) {
代码执行以下操作:
char* hold = malloc(64);
,然后在循环中执行:
while (/* ... */) {
// ...
sprintf(hold,"%d",total);
push(&root, hold);
// ...
}
这将导致堆栈上存储的所有值共享相同的存储,并在更改hold
时将其覆盖。
分配必须在每次使用时进行:
char *hold;
// ...
while (/* ... */) {
// ...
hold = malloc(64);
sprintf(hold,"%d",total);
push(&root, hold);
// ...
}