0

I have this code that gets equations from a .txt file and stores them in a stack, the problem is that when I print them to see the content of the stack, the equations are inverted.

the code is:

// C program to Implement a stack
// using singly linked list
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Declare linked list node
struct Node
{
    char data;
    struct Node *next;
};

int nodesCount;

// Utility function to add an element `x` to the stack

void push(struct Node **top) // insert at the beginning
{
    FILE *myFile;
    myFile = fopen("equations.txt", "r");
    if (myFile == 0)
    {
        printf("file not opened\n");
    }
    else
    {
        printf("file opened \n");
    }


    // allocate a new node in a heap
    struct Node *node = NULL;
    node = (struct Node *)malloc(sizeof(struct Node));

    // check if stack (heap) is full. Then inserting an element would
    // lead to stack overflow
    if (!node)
    {
        printf("Heap Overflow\n");
        exit(-1);
    }

    char equation; //to store the current character in the file

    /*
     * initialize the count to 1
     */
    nodesCount = 0;
    while (!feof(myFile))
    {
        /*
         * Use fgetc to read the file by character
         */
        equation = (char)fgetc(myFile);

        // set data in the allocated node
        node->data = equation;
        // set the .next pointer of the new node to point to the current
        // top node of the list
        node->next = *top;
        // update top pointer
        *top = node;

        /*
         * Each time a node is added, it should be allocated new memory
         */
        node = (struct Node *)malloc(sizeof(struct Node)); // allocate the memory to new node
        // increase stack's size by 1
        nodesCount += 1;
    }
}

// Utility function to check if the stack is empty or not
int isEmpty(struct Node *top)
{
    return top == NULL;
}

// Utility function to return the top element of the stack
int peek(struct Node *top)
{
    // check for an empty stack
    if (!isEmpty(top))
    {
        return top->data;
    }
    else
    {
        printf("The stack is empty\n");
        exit(EXIT_FAILURE);
    }
}

// Utility function to pop a top element from the stack
int pop(struct Node **top) // remove at the beginning
{
    struct Node *node;

    // check for stack underflow
    if (*top == NULL)
    {
        printf("Stack Underflow\n");
        exit(EXIT_FAILURE);
    }

    // take note of the top node's data
    int x = peek(*top);
    printf("Removing %d\n", x);
    node = *top;

    // update the top pointer to point to the next node
    *top = (*top)->next;

    // decrease stack's size by 1
    nodesCount -= 1;

    // free allocated memory
    free(node);

    return x;
}



// Utility function to return the nodesCount of the stack
int size()
{
    return nodesCount;
}

int main(void)
{
    struct Node *top = NULL;
    push(&top);

    if (isEmpty(top))
    {
        printf("The stack is empty\n");
    }
    else
    {
        printf("The stack is not empty\n");
    }

    //Uncomment to check the output :
    struct Node *curr = top;
    while (curr)
    {
        printf("%c", curr->data);
        curr = curr->next;
    }

    return 0;
}

the equation.txt file contains:

a = ((c+d)*a)/(b/(d-a))
b = 4*[x  +  3*(2*x +  1)]
c =  -5*{3  -  2*[1  -  4*(3  -  22)]}
d = 5  +  2*{[3  + (2*x  -  1)  +  x]  -  2}
e = 5  + 9  * 3
(5 + 9)*3
f  (5  + 9)*3
g = 5  +  2*{[3  + (2*x  -  1)  +  x  -  2}
h = 5 +  9 *  3)
i  = 5  + (9  *  3

the output is:

�
3  *  9( +  5 =  i
)3  * 9  + 5 = h
}2  -  x  +  )1  -  x*2( +  3[{*2  +  5 = g
3*)9 +  5(  f
3*)9 + 5(
3 *  9 +  5 = e
}2  -  ]x  +  )1  -  x*2( +  3[{*2  +  5 = d
}])22  -  3(*4  -  1[*2  -  3{*5-  = c
])1  + x*2(*3  +  x[*4 = b
))a-d(/b(/)a*)d+c(( = a

is there a way to make the output look like the equation.txt file or at least make the parenthesis and other braces look in the correct direction?

GHG HGH
  • 37
  • 3
  • 1
    Before casting the return value of `fgetc` to `char`, you should verify that it does not have the value `EOF`. Also, you probably should make the loop condition dependant on the return value of `fgetc`. [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/q/5431941/12149471) – Andreas Wenzel Feb 17 '22 at 18:14
  • thats what a stack does, last in first out. Your code works fine – pm100 Feb 17 '22 at 18:27
  • @pm100: The code works fine, except for the garbage character at the start, which is probably the value `EOF` converted to a `char`, due to incorrectly using `while (!feof(myFile))`. – Andreas Wenzel Feb 17 '22 at 18:31
  • 1
    one bug, if file not found you code carries on, you need a return. And of course 'push' should really push one item, not a whole file – pm100 Feb 17 '22 at 18:31

1 Answers1

0

As already pointed out by someone else in the comments section, a stack is last-in first-out (LIFO). Therefore, it is expected behavior for the data to be inverted.

As far as I can tell, the only bug in your code is the garbage character at the start of the output. The reason for this is is probably that the loop condition

while (!feof(myFile))

is wrong. You may want to read this for further information:

Why is “while ( !feof (file) )” always wrong?

In that loop, you are using the return value of fgetc without first checking whether it is EOF. This check should be performed before casting the int return value to char, because the value EOF is not guaranteed to be representable as a char (it depends on the compiler), and in cases where it is, it would no longer be distinguishable from an actual character after casting it to char.

In the final loop iteration, the function fgetc will probably return EOF. You are casting this value to a char and interpreting it as a character code (although EOF is not a character code). This is probably why the last character pushed onto the stack is a garbage character. Consequently, the first character extracted from the stack will be this garbage character (because a stack is LIFO). This explains why the first character in your posted output is a garbage character.

In order to fix this, I recommend that you don't use

while (!feof(myFile))

as your loop condition, but rather move the fgetc function call into the loop condition, like this:

while ( ( equation = fgetc(myFile) ) != EOF )

However, to ensure that the variable equation is able to represent the value EOF, you must also change its type from char to int. Note that the return value of fgetc is of type int, not char, so it should not be converted to char until you have verified that it does not have the value EOF. Only after that can you be sure that it represents an actual character, and may convert the value to char.

Also note that the additional parentheses are necessary, because != has a higher operator precedence than =.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39