我正在尝试使用链接列表创建一个后缀计算器。 当我编译时,它没有显示任何错误,但是当它被执行时,它将显示Segmentation Fault。我不知道该怎么处理,请帮忙。 这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node {
int num;
struct node *next;
} node;
void push(int num, node **head);
int pop(node **head);
void display(node **head);
int is_empty();
int evaluatePostfix();
struct node *head;
int main() {
head = NULL;
char exp[1000]; // = "5 1 2 + 4 * + 3 -";
printf("Input expression:\t");
fgets(exp, 1000, stdin);
for(int i = 1; i <= strlen(exp); i++) {
if(exp[i] == '\n') {
exp[i] = '\0';
}
else if (exp[0] == '\n') {
printf("stack is empty\n");
exit(0);
}
}
printf("%s = %d\n", exp, evaluatePostfix(exp));
return 0;
}
int evaluatePostfix(char* exp) {
char * token;
int counter = 0;
char temp[256][256];
token = strtok(exp, " ");
while(token != NULL) {
strcpy(temp[counter], token);
counter++;
token = strtok(NULL, " ");
}
for (int i = 0; temp[i]; ++i) {
if (isdigit(*(temp[i]))) {
int val = atoi(temp[i]);
push(val, &head);
}
else {
int val1 = pop(&head);
int val2 = pop(&head);
switch (exp[i]) {
case '+': push(val2 + val1, &head);
printf("%d\n", (*head).num);
break;
case '-': push(val2 - val1, &head); break;
case '*': push(val2 * val1, &head); break;
case '/': push(val1 / val2, &head); break;
}
}
}
return pop(&head);
}
void push (int item, node **head) {
node *temp;
node * get_node(int);
temp = get_node(item);
temp->next = *head;
*head = temp;
}
node *get_node(int item) {
node *temp;
temp = (node*)malloc(sizeof(node));
if (temp == NULL)
printf("\nMemory cannot be allocated");
temp->num = item;
temp->next = NULL;
return(temp);
}
int pop(node **head) {
int item;
node *temp;
item = (*head)->num;
temp = *head;
*head = (*head)->next;
free(temp);
return(item);
}
int is_empty(node *temp) {
if (temp == NULL)
return 1;
else
return 0;
}
void display(node **head) {
node *temp;
temp = *head;
if(head == NULL) {
printf("stack is empty\n");
return;
}
printf("\n");
printf("=========\n");
while(temp!=NULL) {
printf("%d\n", (*temp).num);
temp = (*temp).next;
}
printf("=========\n");
}
答案 0 :(得分:1)
鉴于此声明...
char temp[256][256];
......这里的循环终止条件是错误的:
for (int i = 0; temp[i]; ++i) {
C多维数组不数组引用的Java样式数组。它们是实际数组的数组。当temp[i]
超过您已写入数据的i
元素数时,表达式temp[]
不会为false。
看起来你只想要
for (int i = 0; i < counter; ++i) {
。或者,在开始计算之前没有特别需要标记化。您可以轻松地将函数evaluatePostfix()
中的两个循环合并为一个循环。这样会更简单,并且会删除表达式中术语数量的任何固定限制。
更新:这可能如下所示:
for (token = strtok(exp, " "); token; token = strtok(NULL, " ")) {
/* ... use token instead of temp[i] ... */
}
可以想象您的代码中也存在其他错误,但我在扫描时没有发现任何错误。
答案 1 :(得分:0)
“顺便说一下,标准库中函数的所有标识符都是保留的。 math.h中有一个函数exp(),因此exp属于该类别。 从技术上讲,在代码中使用保留标识符会导致未定义的行为。“
感谢帮帮!将exp更改为另一个变量名称就可以了。这是迄今为止的工作代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node {
int num;
struct node *next;
} node;
void push(int num, node **head);
int pop(node **head);
void display(node **head);
int is_empty(node *temp);
int evaluate(char *expression);
struct node *head;
int main() {
head = NULL;
char expression[1000]; // = "5 1 2 + 4 * + 3 -";
printf("Input expression:\t");
fgets(expression, 1000, stdin);
for(int i = 1; i <= strlen(expression); i++) {
if(expression[i] == '\n') {
expression[i] = '\0';
}
else if (expression[0] == '\n') {
printf("empty stack\n");
exit(0);
}
}
printf("Answer: %d\n", evaluate(expression) );
return 0;
}
int evaluate(char* expression) {
char * token;
int counter = 0;
char temp[256][256];
token = strtok(expression, " ");
while(token != NULL) {
strcpy(temp[counter], token);
token = strtok(NULL, " ");
counter++;
}
for (int i = 0; i < counter; i++) {
if (isdigit(*(temp[i]))) {
int val = atoi(temp[i]);
push(val, &head);
}
else {
int val1 = pop(&head); //pop the last two values from stack
int val2 = pop(&head);
switch (*(temp[i])) { //perform operation
case '+': push(val2 + val1, &head); break;
case '-': push(val2 - val1, &head); break;
case '*': push(val2 * val1, &head); break;
case '/': push(val1 / val2, &head); break;
}
}
}
return pop(&head);
}
void push (int item, node **head) {
node *temp;
node * get_node(int);
temp = get_node(item);
temp->next = *head;
*head = temp;
}
node *get_node(int item) {
node *temp;
temp = (node*)malloc(sizeof(node));
if (temp == NULL)
printf("\nMemory cannot be allocated");
temp->num = item;
temp->next = NULL;
return(temp);
}
int pop(node **head) {
int item;
node *temp;
item = (*head)->num;
temp = *head;
*head = (*head)->next;
free(temp);
return(item);
}
int is_empty(node *temp) {
if (temp == NULL)
return 1;
else
return 0;
}
void display(node **head) {
node *temp;
temp = *head;
if(head == NULL) {
printf("stack is empty\n");
return;
}
printf("\n");
printf("=========\n");
while(temp!=NULL) {
printf("%d\n", (*temp).num);
temp = (*temp).next;
}
printf("=========\n");
}