后缀计算器遇到段错误
postfix calculator having trouble with segfaults
我正在尝试使用链表创建一个后缀计算器。
当我编译时,它没有显示任何错误,但是当它执行时,它会显示 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] = '[=10=]';
}
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");
}
鉴于此声明...
char temp[256][256];
...这里的循环终止条件是错误的:
for (int i = 0; temp[i]; ++i) {
C 多维数组是 不是 Java 数组 references 样式的数组。它们是实际数组的数组。当 i
超过您写入数据的 temp[]
的元素数量时,表达式 temp[i]
不会为假。
看来你只是想要
for (int i = 0; i < counter; ++i) {
。或者,在开始计算之前没有特别需要标记化。您可以轻松地将函数 evaluatePostfix()
中的两个循环合并为一个。这会更简单一些,并且会删除表达式中项数的任何固定限制。
更新: 可能看起来像这样:
for (token = strtok(exp, " "); token; token = strtok(NULL, " ")) {
/* ... use token instead of temp[i] ... */
}
可以想象你的代码中还有其他错误,虽然我在扫描时没有发现任何错误。
"顺便说一句,标准库中函数的所有标识符都是保留的。
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] = '[=10=]';
}
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");
}
我正在尝试使用链表创建一个后缀计算器。 当我编译时,它没有显示任何错误,但是当它执行时,它会显示 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] = '[=10=]';
}
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");
}
鉴于此声明...
char temp[256][256];
...这里的循环终止条件是错误的:
for (int i = 0; temp[i]; ++i) {
C 多维数组是 不是 Java 数组 references 样式的数组。它们是实际数组的数组。当 i
超过您写入数据的 temp[]
的元素数量时,表达式 temp[i]
不会为假。
看来你只是想要
for (int i = 0; i < counter; ++i) {
。或者,在开始计算之前没有特别需要标记化。您可以轻松地将函数 evaluatePostfix()
中的两个循环合并为一个。这会更简单一些,并且会删除表达式中项数的任何固定限制。
更新: 可能看起来像这样:
for (token = strtok(exp, " "); token; token = strtok(NULL, " ")) {
/* ... use token instead of temp[i] ... */
}
可以想象你的代码中还有其他错误,虽然我在扫描时没有发现任何错误。
"顺便说一句,标准库中函数的所有标识符都是保留的。 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] = '[=10=]';
}
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");
}