Bug on mathematical expression verification - c

I'm need to verify if ()[]{} of a mathematical expression are all closed.
Such {4 + 9} − (9 − 8) << are correct and ((()) aren't correct.
Using a stack builded using linked list.
Like if the actual index of the string have "{" or "[" or "(" push it to stack and if the index have ")" or "]" or "}" pop the top of stack and verify if are matching with the actual element. If stack are empty in the end, expression are correct, or if during execution loop the closing symbol don't match or stack isn't empty, the expression aren't correct.
structs
struct stack{char string[1];int index;struct stack *next;};
struct retpop{char string[1];struct stack *top;};
functions pop/push
struct stack *push(struct stack *topo, char *se){
struct stack *temp;
if (top == NULL)
{
top =(struct stack *)malloc(sizeof(struct stack ));
top->next= NULL;
top->index = 0;
top->string[0] = 0;
snprintf(top->string, 1, "%c", se[0]);
}
else
{
temp =(struct stack *)malloc(sizeof(struct stack ));
temp->next = top;
temp->index = top->index + 1;
temp->string[0] = 0;
snprintf(temp->string, 1, "%c", se);
top = temp;
}
return top;
}
struct retpop pop(struct stack *top){
struct retpop return1;
if (top == NULL)
{
printf("EMPTY STACK\n");
return;
}
else{
struct stack *top1;
top1 = top;
snprintf(return1.string, 1, "%c", top1->string[0]);
top1 = top1->next;
free(top);
top = top1;
}
retorno.top = top;
return return1;
}
functions to analisis
void process_string(char string[100]){
struct stack *top;
top = NULL;
int i = 0;
struct stack *temp;
int nullifier = 0;
char *temp;
struct retpop temppop;
while(i < (strlen(string)-1)){
snprintf(temp, 1, "%c", string[i]);
if(temp[0] == '}'){
temppop = pop(top);
top = temppop.top;
if((char)temppop.string[0] != '{'){
nullifier = 1;
}
}
if(temp[0] == ']'){
temppop = pop(top);
top = temppop.top;
if((char)temppop.string[0] != '['){
nullifier = 1;
}
}
if(temp[0] == ')'){
temppop = pop(top);
top = temppop.top;
if((char)temppop.string[0] != '('){
nullifier = 1;
}
}
if(temp[0] == '{'){
top = push(top,"{");
}
if(temp[0] == '['){
top = push(top,"[");
}
if(temp[0] == '('){
top = push(top,"(");
}
i++;
}
if((topo != NULL) || (anulador == 1)){
printf("\nNOT VALID\n");
}
else{
printf("\nVALID\n");
}
}
The problem are, the code correctly analise things like []{}()or [][][][][] but when i use {}{}{}{}{} or ()()()()() or {[()()()][()()()]} the stack return buggy values and the expression became false :/ What can I do? The problem are on my code?
(please ignore the use of stack inside the code, on my code i'm using the other word from my language, but to display in a better way i placed "stack" on code)

Related

Stack Overflow in Balanced Parenthesis

I am trying to write a program to check if a string of brackets is balanced or not. If balanced, I do not want any output. But if it is not balanced then I want it to return the brackets needed to balance it. For example '([])' should be balanced and '({}' should be unbalanced and should return "open: )". The code seems to work fine until I have two or more brackets left open. So if I input '({' my code works but when I add a few more characters like '([])([' it fails because of a stack overflow. I do not understand what the error could be or how to fix it.
Here is my code:
void push(struct sNode** top_ref, int new_data){
struct sNode* new_node = (struct sNode*)malloc(sizeof(struct sNode));
if (new_node == NULL) {
printf("Stack overflow \n");
getchar();
exit(0);
}
new_node->data = new_data;
new_node->next = (*top_ref);
(*top_ref) = new_node;
}
int pop(struct sNode** top_ref){
char res;
struct sNode* top;
if (*top_ref == NULL) {
printf("Stack overflow \n");
getchar();
exit(0);
}else {
top = *top_ref;
res = top->data;
*top_ref = top->next;
free(top);
return res;
}
}
// Returns 1 if character1 and character2 are matching left and right Brackets
bool isMatchingPair(char character1, char character2)
{
if (character1 == '(' && character2 == ')')
return 1;
else if (character1 == '{' && character2 == '}')
return 1;
else if (character1 == '[' && character2 == ']')
return 1;
else
return 0;
}
// Return 1 if expression is balanced
int areBracketsBalanced(char exp[]){
int i = 0;
struct sNode* stack = NULL;
while (exp[i]){
if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[')
push(&stack, exp[i]);
if (exp[i] == '}' || exp[i] == ')' || exp[i] == ']') {
if (stack == NULL){
printf("%d:%c\n",i,exp[i]);
return 0;
}else if (!isMatchingPair(pop(&stack), exp[i])){
printf("%d:%c\n",i,exp[i]);
return 0;
}
}
i++;
}
if (stack != NULL){
printf("open: ");
while(stack!=NULL){
if(pop(&stack)=='('){
printf("%c",')');
}else if(pop(&stack)=='['){
printf("%c",']');
}else if(pop(&stack)=='{'){
printf("%c",'}');
}
}
printf("\n");
return 0;
}
return 0;
}
int main(int argc, char* argv[])
{
char *exp = (char *)malloc(strlen(argv[1]) * sizeof(char));
for(int i = 0; i<strlen(argv[1]); i++){
exp[i] = argv[1][i];
}
//char exp[] = "([])([";
areBracketsBalanced(exp);
return 0;
}
As it has been pointed out in comments, your exp in main is wrong as it end up without a zero termination. Actually there is no need for it... just pass argv[1] to the function.
int main(int argc, char* argv[])
{
if (argc > 1)
{
areBracketsBalanced(argv[1]);
}
else
{
puts("Missing argument");
}
return 0;
}
Besides that, you have a problem here:
while(stack!=NULL){
if(pop(&stack)=='('){
printf("%c",')');
}else if(pop(&stack)=='['){
printf("%c",']');
}else if(pop(&stack)=='{'){
printf("%c",'}');
}
}
Each of these pop(&stack) will change stack and maybe cause it to be NULL. At worst you do 3 pop-operations before checking for NULL. That's not good.
Change the code so that you have one pop operation before the if statements. Save the result in a local variable that you use for the if statement. Like:
while(stack!=NULL){
int value = pop(&stack);
if(value == '('){
printf("%c",')');
}else if(value == '['){
printf("%c",']');
}else if(value == '{'){
printf("%c",'}');
}
}

Infinite loops with a linked list

I'm working on a program that takes an input of numbers from stdin and computes the median of the sequence and prints it out as a float. I'm currently getting an infinite loop in the function
len(struct node *)
at the for loop and I'm not sure why.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
float *val;
struct node *next;
};
int len(struct node *list) {
int i = 0;
struct node *temp = list;
for (i = 0; temp != NULL; i++) {
temp = temp->next;
}
return i;
}
float median(int size, struct node list) {
struct node temp = list;
int i = 0;
if (size == 1) {
return *temp.val;
} else
if (size == 2) {
return (*(temp.val) + *(temp.next->val)) / 2;
} else {
if (size / 2 == 1) {
for (i = 3; i != (size / 2) - 1; i++) {
temp = *(temp.next);
}
return *temp.val;
} else {
for (i = 3; i != (size / 2); i++) {
temp = *(temp.next);
}
return (*(temp.val) + *(temp.next->val)) / 2;
}
}
}
int main() {
struct node *tmpnode;
tmpnode = malloc(sizeof(struct node));
tmpnode->next = NULL;
struct node *list = NULL;
list = tmpnode;
float temp = 0;
int err = 0;
int size = 0;
while ((err = scanf("%f", &temp)) != EOF) {
if (err < 1) {
fprintf(stderr, "Error: non-integer character inputted\n");
return 1;
}
tmpnode->val = &temp;
tmpnode->next = list;
list = tmpnode;
}
size = len(list);
if (size == 0) {
fprintf(stderr, "Error: no inputs found");
return 1;
}
printf("%f\n", median(size, *list));
return 0;
}
Edit: I've fixed the infinite loop, but now I'm getting a segfault at temp = *(temp.next) in median(). Do I need to allocate for temp?
You created only one node and assigned next of the node to itself, so this is cause of the infinite loop.
Create new nodes and link them in the input loop.
Assigning address of temp to all nodes is also not good.
Your main() function should be like this:
int main(void){
struct node *tmpnode;
tmpnode = malloc(sizeof(struct node));
if(tmpnode == NULL){
perror("malloc 1");
return 1;
}
tmpnode->next = NULL;
struct node *list = NULL;
list = tmpnode;
float temp = 0;
int err = 0;
int size = 0;
while((err = scanf("%f", &temp)) != EOF){
if(err < 1){
fprintf(stderr, "Error: non-integer character inputted\n");
return 1;
}
tmpnode->val = malloc(sizeof(float));
if(tmpnode->val == NULL){
perror("malloc 2");
return 1;
}
*tmpnode->val = temp;
tmpnode->next = malloc(sizeof(struct node));
if(tmpnode->next == NULL){
perror("malloc 3");
return 1;
}
tmpnode = tmpnode->next;
tmpnode->val = NULL;
tmpnode->next = NULL;
}
size = len(list);
if(size == 0){
fprintf(stderr, "Error: no inputs found");
return 1;
}
printf("%f\n", median(size, *list));
/* code to free the list should be here */
return 0;
}
(I gave input 1 2 3 4 5 and this program's output was 1.500000, which might be wrong)
If you're looking for the median you would have to arrange the nodes in order and get the number that is in the middle.If the number of nods is even and there is no middle you should add the two middlemost numbers and divide them by two.
Is the sequence in order? If not you're miscalculating the median.
Supposing the sequence is in order.
I didn't really understand the usefulness of this statement
if(size/2 == 1)
Maybe you're trying to see if the size is odd. In that case you should do:
> if(size%2 == 1)
Why the list is probably looping might be due to this
for(i = 3; i != (size/2); i++){
temp = *(temp.next);
}
Suppose you pass a 5 to the function size/2=2 (decimal part is lost), so it'll keep on going until an overflow occurs and it actually reaches 2, making your program most probably seg_fault in the process.
Start from i=0, because even though you started from 3 your current node is not the third one but the FIRST ONE.
Good luck hope this helps!!!!

Error allocating memory for temp in queue push in c invalid write size of 8 from valgrind

This is my push function
void push(struct Map *map, struct Location location){
struct Node *temp = map->front;
temp->loc = location; //this line causes the error
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
free(temp);
}
and I am getting this error
==2301== Invalid write of size 8
==2301== at 0x401148: push (3146.c:239)
==2301== by 0x400DE7: findEntrance (3146.c:164)
==2301== by 0x400820: main (3146.c:55)
==2301== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2301==
I am doing a breadth first search on a grid of characters arranged to be a maze. I have been having trouble getting no memory leaks so I have finally found that using malloc helps, but I don't understand why I cannot do this data assignment without a segfault
The alternative is to not free it and have memory leaks, which I don't think is an acceptable solution. Where is my logic wrong?
Below this is the whole program
#include <stdio.h>
#include <stdlib.h>
struct Location;
struct Map;
struct Node;
//function names seem to self describe
void pathFinder(struct Map*);
void findEntrance(struct Map*);
void readInMap(struct Map*);
void printMap(struct Map*);//to screen
/* Q funcs */
void pop(struct Map*);
void push(struct Map*, struct Location);
struct Location {// simple location type
int x;
int y;
};
struct Node {//standard linked list node
struct Location loc;
struct Node *next;
};
struct Map { //variable size encompassing array, and dimension variables
char arr[100][100];
int xLength;//dimensions
int yLength;
int complete;
struct Node *rear;//Q pointers
struct Node *front;
struct Node *currLoc; //temp for BFS
struct Location entrance;
};
int main(){
struct Map map;//the one map to rule them all
map.xLength = 0;//map dimensions
map.yLength = 0;
map.front = NULL; // queue pointers init
map.rear = NULL;
map.currLoc = NULL;
map.entrance.x = 0;
map.entrance.y = 0;
map.complete = 0;
readInMap(&map);
findEntrance(&map);//start off by finding where to start
pathFinder(&map); // problem solver method
printMap(&map);
free(map.front);
free(map.rear);
free(map.currLoc);
return 0;
}
void pathFinder(struct Map *map){
int x;//should be the entrance already pushed from findEntrance
int y;
int done = 0;
struct Location temp;
temp.x = 0;// temp for pushing locations that are adjacent 0's
temp.y = 0;
while(map->front != NULL){
map->currLoc = map->front;//currLoc is just a copy so that we can pop the map location of currLoc from Q
pop(map);// pop so it cant be used twice in this loop
x = map->currLoc->loc.x;
y = map->currLoc->loc.y;
temp.x = 0;
temp.y = 0;
if(map->arr[y][x] == '0'){//protection of 1 values from replacement
map->arr[y][x] = 'X';//replace the array position loc w x
}
if(map->arr[y][x] == '0'){//protection of 1 values from replacement
map->arr[y][x] = 'X';//replace the array position loc w x
printf("test\n");
}
/* find adjacent 0's */
if((y < map->xLength)&&(map->arr[y+1][x] == '0')){
temp.x = x;
temp.y = y+1;
push(map, temp);
}
if((x < map->xLength)&&(map->arr[y][x+1] == '0')){
temp.x = x+1;
temp.y = y;
push(map, temp);
}
if((y > 0)&&(map->arr[y-1][x] == '0')){
temp.x = x;
temp.y = y-1;
push(map, temp);
}
if((x > 0)&&(map->arr[y][x-1] == '0')){
temp.x = x-1;
temp.y = y;
push(map, temp);
}
if((x == 0)||(x == map->xLength)||(y == 0)||(y == map->yLength)){ //then its not on the edge
if((x != map->entrance.x)&&(y != map->entrance.y)){
map->front = NULL;
map->complete++;
}
}
}
}
void findEntrance(struct Map *map){
struct Location entrance;
int done = 0;
int y=0;//index of current row depth
int x=0;//index of current column depth
if (done == 0){
for (x=0;x<=map->xLength;x++){ // top row
if (map->arr[y][x] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(y=0;y<=map->yLength;y++){//down the right side
if (map->arr[y][map->xLength] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(x;x>=0;x--){//bottom row RtoL
if (map->arr[map->yLength][x] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(y;y>=0;y--){//up the left side
if (map->arr[y][0] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
map->entrance = entrance;
push(map, map->entrance);
}
void readInMap(struct Map *map){
FILE *fptr;
char c;
char file_name[20];
int i,j;
int rows;
int cols;
int x,y;
printf("Size\n");
printf("Rows:");
scanf("%i", &rows);
printf("Columns:");
scanf("%i", &cols);
map->xLength = cols-1; //[y][xLength]
map->yLength = rows-1; //[yLength][x]
for (x=0;x<100;x++){
for (y=0;y<100;y++){
map->arr[x][y] = '1';//whole array is 1
}
}
printf("Type in the name of the file containing the Field\n");
scanf("%s",file_name);
fptr=fopen(file_name, "r");
for (i = 0; i <= map->xLength; i++){
for (j = 0; j <= map->yLength; j++){
c=fgetc(fptr); //handles new line character and spaces
while ( !((c == '1') || (c =='0')) ) {
c=fgetc(fptr);
}
map->arr[i][j] = c;
}
}
printf("\n");
fclose(fptr);
}
void printMap(struct Map *map){
int y;//index of current row depth
int x;//index of current column depth
for (x=0;x<=map->xLength;x++){
for (y=0;y<=map->yLength;y++){//current pos (x,y)
printf("%c", map->arr[x][y]);
}
printf("\n");
}
if(map->complete != 0){
printf("\n An exit to the maze was found that is not the entrance\n");
}else{
printf("\n No exit was found \n");
}
}
void pop(struct Map *map){
if (map->front != NULL){//if not empty
if (map->front == map->rear){
map->rear = NULL;//if the line length is 1, empty it
map->front = NULL;
}else{
map->front = map->front->next;//next in line
}
}else{
map->rear = NULL;//empty out the queue
map->front = NULL;
}
}
void push(struct Map *map, struct Location location){
struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
temp->loc = location;
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
free(temp);
}
When the Map is empty, both front and rear are NULL. So temp->loc is dereferencing a NULL pointer.
You need to malloc the new node and add that to the list. Additionally, you don't want to free here, as that deallocates the memory that you just added to the list.
void push(struct Map *map, struct Location location){
struct Node *temp = malloc(sizeof(struct Node));
temp->loc = location;
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
}
In pop is where you want to deallocate the memory:
void pop(struct Map *map){
struct Node *temp = map->front;
if (map->front != NULL){//if not empty
if (map->front == map->rear){
map->rear = NULL;//if the line length is 1, empty it
map->front = NULL;
}else{
map->front = map->front->next;//next in line
}
free(temp);
}else{
map->rear = NULL;//empty out the queue
map->front = NULL;
}
}

Stack implementation in C producing confusing results

For a component of an assignment for college we have to implement a stack, which I think I've done well enough for it to be functional. When I'm testing the stack by itself it seems to work fine, however when I'm using it as part of my solution it behaves differently, and I can't figure out why. Can someone please point out my mistake? Thanks.
Edit: I can feel a lot of "how does it behave differently?" comments are on the way, so here's what I've noticed. When running the Testing stack section of main, all the operations execute and print perfectly fine, but when I'm running the second part of main and comment out the testing part instead, the program crashes when I'm trying to push onto the stack - something that didn't fail previously.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct stackNode {
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
typedef enum {
false, true
} t_bool;
void* emalloc(size_t s) {
void* p = malloc(s);
if (NULL == p) {
fprintf(stderr, "Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
return p;
}
void print_array(char* array, size_t n){
int i;
printf("[");
for(i = 0; i < n - 1; i++){
printf("%c, ", array[i]);
}
printf("%c]\n", array[i]);
}
// Determine if c is an operator.
int isOperator(char c) {
char ops [6] = {'+', '-', '*', '/', '%', '^'};
int i;
for (i = 0; i < 6; i++)
if (ops[i] == c) return true;
return false;
}
int op_priority(char c) {
if (c == '+' || c == '-') return 0;
else if (c == '*' || c == '/') return 1;
else if (c == '^' || c == '%') return 2;
return -1;
}
// Determine if the precedence of operator1 is less than, equal to, or greater than
// the precedence of operator2. The function returns -1, 0 and 1, respectively.
int precedence(char op1, char op2) {
int op1_p = op_priority(op1);
int op2_p = op_priority(op2);
if (op1_p < op2_p) return -1;
else if (op1_p > op2_p) return 1;
else return 0;
}
// Push a value on the stack.
void push(StackNodePtr *topPtr, char value) {
StackNodePtr temp = (StackNodePtr) emalloc(sizeof (StackNode));
temp->data = value;
temp->nextPtr = *topPtr;
*topPtr = temp;
}
// Pop a value off the stack.
char pop(StackNodePtr *topPtr) {
StackNodePtr t = *topPtr;
if (NULL != *topPtr) {
char c = t->data;
*topPtr = t->nextPtr;
free(t);
return c;
} else {
printf("Stack is empty.\n");
return '\0';
}
}
// Return the top value of the stack without popping the stack.
char peek(StackNodePtr topPtr) {
if (NULL != topPtr) {
return topPtr->data;
} else {
printf("Stack is empty.\n");
}
}
// Determine if the stack is empty.
int isEmpty(StackNodePtr topPtr) {
if (NULL == topPtr) return true;
return false;
}
// Prints the stack
void printStack(StackNodePtr topPtr) {
if (!isEmpty(topPtr)){
StackNodePtr t = topPtr;
while (NULL != t) {
printf("%c\t", t->data);
t = t->nextPtr;
}
printf("NULL\n");
} else {
printf("Stack is empty.\n");
}
}
// Convert the infix expression to postfix notation.
void convertToPostfix(char infix [], char postfix [], int expression_length) {
printf("At top of cnvToPostfix\n");
int infix_count = 0;
int postfix_count = 0;
////////////////////////////////////////////
StackNodePtr *stack;
push(stack, '(');
printStack(*stack);
////////////////////////////////////////////
infix[expression_length] = ')';
while (isEmpty(*stack)) {
char current = infix[infix_count++];
if (isdigit(current)) {
postfix[postfix_count++] = current;
} else if (current == '(') {
push(stack, current);
} else if (isOperator(current)) {
while (true) {
char top = peek(*stack);
if (isOperator(top) && precedence(current, top) >= 0) {
postfix[postfix_count++] = pop(stack);
} else {
break;
}
}
push(stack, current);
}
else if (current == ')') {
while (true) {
char top = peek(*stack);
if (top == '(') {
pop(stack);
break;
} else {
postfix[postfix_count++] = pop(stack);
}
}
}
}
}
int main() {
printf("Testing stack\n");
printf("Pushing 1, 2, and 3 onto stack, peeking and popping.\n");
StackNodePtr *stack;
push(stack, '1');
push(stack, '2');
push(stack, '3');
printf("Printing stack\n\n");
printStack(*stack);
printf("Peek: %c\n", peek(*stack));
printf("Pop: %c\n", pop(stack));
printf("Printing stack\n");
printStack(*stack);
/*
printf("Enter the infix expression.\n");
char c;
char infix [1024];
int count = 0;
while ((scanf("%c", &c)) == 1) {
if ((int) c == 10) break;
infix[count++] = c;
}
printf("The original infix expression is:\n");
print_array(infix, count);
char postfix [count];
convertToPostfix(infix, postfix, count);
printf("The expression in postfix notation is:\n");
print_array(postfix, count);
*/
return 0;
}
I see at least one immediate problem:
StackNodePtr *stack;
push(stack, '1');
Where is the initialisation for your stack? Use of uninitialised pointers is instant "undefined behaviour" territory.
If you look closely at your push code, you'll see it inserts the new item before the current one but set the new item's nextPtr pointer to the previous (uninitialised) value.
That means, the last item in the stack won't actually point to NULL.
You're not really initialising your stacks:
StackNodePtr *stack;
push(stack, '(');
It's also potentially confusing having StackNodePtr being a pointer type, and stack being a pointer to that type. You need to be clear in every possible usage how many levels of indirection should be applied.
To start with, imagine passing the new stack firstly to isEmpty:
StackNodePtr *stack;
printf("%d\n", isEmptypush(*stack));
What's isEmpty going to do on the value it is passed?
I think what you want instead is:
StackNodePtr stack = NULL;
push(&stack, '(');
Other uses of stack in that function should similarly be changed from *stack to stack, or stack to &stack.

The functions && Linked List

I did my best with this program but I could not know where is the error?? I'll explain the program. In this program I should implement a stack of integers as linked list, using a global variable to point to the top of the stack by using these methods:
int push(int i);
push i on the stack, return 1 if successful else return 0.
int pop();
pop number from stack. if stack empty return 0;
I did create new method call int stackEmpty(); and the two method above.
Every time I run my program it's push the numbers into the stack but the pop doesn't work. Here my code:::
#include <stdio.h>
#include <stdlib.h>
typedef struct stack Stack;
struct stack
{
int number;
Stack *next;
};
Stack *top = NULL;
int push(int i);
int count();
int stackEmpty();
int pop();
int main()
{
char op;
int i, x;
printf("Welcome to my stack\n");
printf("p to pop, s to push, c to count, q to quit\n");
while (op != 'q')
{
scanf("%c", &op);
if (op == 'p')
{
x = pop();
if (x == 0)
{
printf("Stack is empty\n");
}
else
{
printf("%d popped\n", pop());
}
}
else if (op == 'c')
{
i = count();
printf("%d numbers on stack\n", i);
}
else if (op == 's')
{
printf("Enter number: ");
scanf("%d", &i);
x = push(i);
if (x == 1 || x == 2)
{
printf("%d puched :: state%d\n", i, x);
}
else
{
printf("faill %d\n", x);
}
}
else if (op == 'q')
{
return 0;
}
}
return 0;
}
int stackEmpty()
{
if (top == NULL)
{
return 1;
}
else
{
return 0;
}
}
int count()
{
int counter = 0;
if (top == NULL)
{
return counter;
}
else
{
while (top != NULL)
{
top = top->next;
counter++;
}
return counter;
}
}
int push(int i)
{
Stack *head;
Stack *next;
Stack *new;
int state;
int m;
head = top;
new = (Stack *) malloc(sizeof(Stack));
if (new == NULL)
{
state = 0;
} new->number = i;
m = stackEmpty();
if (m == 1)
{
head = new;
top = head;
head->next = NULL;
state = 1;
}
else
{
while (head != NULL)
{
if ((next = head->next) == NULL)
next = new;
next->next = NULL;
state = 2;
break;
head = top->next;
next = head->next;
}
top = head;
}
return state;
}
int pop()
{
Stack *head;
int state;
int m;
head = top;
if (head == NULL)
{
state = 0;
}
m = stackEmpty();
if (m == 1)
{
state = 0;
}
else
{
state = head->number;
top = head->next;
free(head);
}
return state;
}
Several problems:
top is your supposed head of the stack I assume. In count you advance top until it is NULL - thus once you called count you have "lost" your stack.
A stack is a LIFO queue (last in first out). Your push would implement a FIFO (first in first out) by appending new elements at the end.
Your push is not actually adding anything to the list. You are just assiging new to next but you are not pointing to next from anywhere in your list.
When using pop you are calling it twice (once for removing the element and once for printing). Therefore you remove two elements whenever you go down that code path. A better implementation would be to write a peek function which returns the top element without removing it and the pop function simply removes it (indicating success with 1 and fail with 0)
A push for a stack goes like this:
Create a new element
Point to your current head as the next element
Make your new element the new head of the stack
No loop needed. It's an O(1) operation.
You are not pushing correctly. You are changing next which is a local variable. you are not changing the "next" value in you list tail.
One problem is that you pop(), then check result, then pop() again while printing. You're popping twice for each time you try to print.
Another error:
while (head != NULL)
{
if ((next = head->next) == NULL)
next = new;
next->next = NULL;
state = 2;
break;
head = top->next;
next = head->next;
}
Should be:
while (head != NULL)
{
if ((next = head->next) == NULL)
{
next = new;
next->next = NULL;
state = 2;
break;
}
head = top->next;
next = head->next;
}
At least, that's what your original indentation seems to indicate.

Resources