c语言 - 为什么我不能遍历这个堆栈?



我正在尝试用实现堆栈制作一个括号检查器。如果输入具有正确的括号模式,程序将打印有效

input: {[()]}
output: valid
input: {()[()]}
output: valid
input: (()))
output: unvalid
continuously

但在我输入数据后会发生什么:

()
the program prints this unlimited loop
valid
valid
valid
valid
valid
. . . and so on
same with
(()))

如果放断,它工作正常;在这里,但它不会是连续的,会立即结束程序,并且不会再次要求输入。

if(isempty(stack)){
printf("Valid parenthesis expressionn");
break;
} else{
printf("Invalid parenthesis expressionn");
break;
}

我似乎找不到发生这种事的原因,有人能帮我或给我一些建议吗?这样我就可以循环请求输入并只打印一次有效/无效?

#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct data{
char parent;
struct data *next;
}DATA;
void push(DATA **stack, char parentheses);
int isempty(DATA *stack);
void pop(DATA **stack);
int top(DATA *stack);
int main(int argc, char const *argv[]){
DATA *stack;
char parentheses[100];
int i, flag = 1;
do{
//PUSH
stack = NULL;
printf("Enter parentheses: ");
scanf("%[^n]", &parentheses);

if(strcmp(parentheses, "-1") == 0){
break;
}
for(i = 0; i < strlen(parentheses); i++){
if(parentheses[i] == '{' || parentheses[i] == '[' || parentheses[i] == '('){
push(&stack, parentheses[i]);
} else if (stack == NULL){
printf("Invalid parenthesis expressionn");
break;
} else if(parentheses[i] == '}' && top(stack) == '{'){
pop(&stack);
} else if (parentheses[i] == ']' && top(stack) == '['){
pop(&stack);
} else if (parentheses[i] == ')' && top(stack) == '('){
pop(&stack);
} else if(parentheses[i] != '{' || parentheses[i] != '[' || parentheses[i] != '(' || parentheses[i] != '}' || parentheses[i] != ']' || parentheses[i] != ']') {
printf("Invalid parenthesis expressionn");
break;
}
}
//POP
if(isempty(stack)){
printf("Valid parenthesis expressionn");
} else{
printf("Invalid parenthesis expressionn");
}
}while(1);
return 0;
}
void push(DATA **stack, char parentheses){
DATA *node = (DATA*) malloc(sizeof(DATA));
node -> parent = parentheses;
node -> next = NULL;
if(!isempty(*stack)) node->next = *stack;
*stack = node;
}
int isempty(DATA *stack){
if(stack == NULL) return 1;
else return 0;
}
void pop(DATA **stack){
DATA *temp = *stack;
*stack = (*stack)->next;
free(temp);
}

int top(DATA *stack){
return stack -> parent; //STACK !ISEMPTY
}

scanf("%[^n]", &parentheses);

必须是

scanf(" %[^n]", parentheses);

请注意"%"前面的空格,以绕过来自前一个输入的换行符,在第二个转弯时不使用它scanf将不起任何作用。为了检测这种情况以及任何无效输入,我鼓励您始终检查scanf返回的值。

如果输入至少有100个字符,请执行

if (scanf(" %99[^n]", parentheses) != 1) {
/* EOF */
return -1;
}

圆括号是一个数组,如果您想使用"&",它将指定索引0,因此&括号[0]

注意标志是未使用的

当您检测到无效的事例时,您可以指示"有效括号表达式":

pi@raspberrypi:/tmp $ ./a.out
Enter parentheses: (
Invalid parenthesis expression
Enter parentheses: )
Invalid parenthesis expression
Valid parenthesis expression

当的之后堆栈不为空时,如果没有释放仍然存在的已分配元素,则表示内存泄漏。

因为你只需要在堆栈中保存字符,所以只使用一个char数组在内存中会更简单、更便宜。因为输入被限制为99(没有最后的null字符(,所以堆栈也需要保存99个字符,事实上括号可以用于堆栈

建议仍然使用您的堆栈,修复问题,同时减少测试次数并简化堆栈功能:

#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct data{
char parent;
struct data *next;
} DATA;
void push(DATA **stack, char parentheses);
int isempty(DATA *stack);
void pop(DATA **stack);
int top(DATA *stack);
int main(int argc, char const *argv[]){
DATA *stack = NULL;
char parentheses[100];
char * p;
while (fputs("Enter parentheses: ", stdout),
(scanf(" %99[^n]", parentheses) == 1) && strcmp(parentheses, "-1")) {
for (p = parentheses; *p; ++p) {
if  ((*p == '{') || (*p == '[') || (*p == '('))
push(&stack, *p);
else {
char o;
if (*p == '}')
o = '{';
else if (*p == ')')
o = '(';
else if (*p == ']')
o = '[';
else
o = 0;
if (isempty(stack) || (top(stack) != o))
break;
pop(&stack);
}
}
if (!isempty(stack) || *p) {
puts("Invalid parenthesis expression");
while (! isempty(stack))
pop(&stack);
}
else if (!*p)
puts("Valid parenthesis expression");
}
return 0;
}
void push(DATA **stack, char parentheses) {
DATA *node = malloc(sizeof(DATA));
node->parent = parentheses;
node->next = *stack;
*stack = node;
}
int isempty(DATA *stack) {
return (stack == NULL);
}
void pop(DATA **stack) {
DATA *temp = *stack;
*stack = (*stack)->next;
free(temp);
}
int top(DATA *stack) {
return stack->parent;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -Wall s.c
pi@raspberrypi:/tmp $ ./a.out
Enter parentheses: ({[]}())
Valid parenthesis expression
Enter parentheses: (
Invalid parenthesis expression
Enter parentheses: )
Invalid parenthesis expression
Enter parentheses: (]
Invalid parenthesis expression
Enter parentheses: -1
pi@raspberrypi:/tmp $ 

最新更新