Reputation: 117
I'm trying to make a parentheses checker with implementing stack. The program will print valid if the input have a correct parentheses pattern
input: {[()]}
output: valid
input: {()[()]}
output: valid
input: (()))
output: unvalid
continuously
But what happen after i input the data is :
()
the program prints this unlimited loop
valid
valid
valid
valid
valid
. . . and so on
same with
(()))
It works normally if put break; on here, but it won't be continuous and would instantly ends the program, and wont ask for the input again.
if(isempty(stack)){
printf("Valid parenthesis expression\n");
break;
} else{
printf("Invalid parenthesis expression\n");
break;
}
I can't seem to find the reason why this happened, can anyone help me or give me some advice about what's going on? So that I can loop to ask for input and print the valid/invalid just only one time?
#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 expression\n");
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 expression\n");
break;
}
}
//POP
if(isempty(stack)){
printf("Valid parenthesis expression\n");
} else{
printf("Invalid parenthesis expression\n");
}
}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
}
Upvotes: 0
Views: 73
Reputation: 32586
scanf("%[^\n]", &parentheses);
must be
scanf(" %[^\n]", parentheses);
notice the space before the '%' to bypass the newline coming from a previous input, without it on the second turn scanf does nothing. To detect that case and also any invalid input I encourage you to always check the value scanf returns.
In case the input has at least 100 characters you write out of parentheses, do
if (scanf(" %99[^\n]", parentheses) != 1) {
/* EOF */
return -1;
}
parentheses is an array, if you want to use "&" it is specifying the index 0 so &parentheses[0]
Note flag is unused
When you detect an invalid case you can indicate "Valid parenthesis expression" :
pi@raspberrypi:/tmp $ ./a.out
Enter parentheses: (
Invalid parenthesis expression
Enter parentheses: )
Invalid parenthesis expression
Valid parenthesis expression
When the stack is not empty after the for you do not free the still present allocated elements, you have memory leaks.
Because you just save characters in the stack it is much more simple and cheaper in memory to just use an array of char. Because the input is limited to 99 (without the final null character) the stack needs to save 99 characters too, and in fact parentheses can be used for the stack
A proposal still using your stack, fixing problems and also reducing the number tests and simplifying stack functions :
#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;
}
Compilation and execution:
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 $
Upvotes: 1