0

The program is not complete. I can add enqueue nodes, display the list of nodes, and find the top of the node, etc... But when I try to dequeue and return a node from the dequeue function the customer's name gets jumbled up. This is a queue implementation in linked list. The application is similar to an order system from a fast-food chain.

Also, I was expected to have this operation in my program: "INIT(): creates and returns an empty queue." Did I do it right?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLENGTH 20

struct Node{
    char name[MAXLENGTH];
    char order[MAXLENGTH];
    struct Node* link;
};

struct Node* Init();
int Empty(struct Node*, struct Node*);
struct Node* Front(struct Node*);
void AskOrder(struct Node**, struct Node**);
void EnQueue(char*, char* , struct Node** , struct Node** );
struct Node* DeQueue(struct Node**, struct Node** );
void display(struct Node* );

int main()
{
    
    struct Node* front = NULL;
    struct Node* rear = NULL;
    int ch = -1;
    struct Node* printme = NULL;
    
    while(ch!=0)
    {
        printf("ORDER LIST:");    
            if (Empty(front, rear) != 1)
                display(front);
                
        printf("\n\nJohn's Store Menu:\n"
                "\n [1] Fall in line"
                "\n [2] Serve order"
                "\n [3] Next order"
                "\n [4] Closing time"
                "\n [0] Exit\n"
                "\nEnter choice: ");
        scanf("%d", &ch);
        switch(ch)
        {
            case 1:
                AskOrder(&front, &rear);
                break;
            case 2:
                if(Empty(front, rear) != 1)
                {
                    printme = DeQueue(&front, &rear);
                    printf("\nNow serving [%s] to customer [%s].\n", printme->order, printme->name);
                }else
                    printf("The QUEUE is EMPTY. No orders to serve.");
                break;
            case 3:
                if(Empty(front, rear) != 1)
                {
                    printme = Front(front);
                    printf("\nNext order: [%s] of customer [%s].\n", printme->order, printme->name);    
                }else
                    printf("The QUEUE is EMPTY. No orders to serve.\n");
                break;
            case 4:
                if(Empty(front, rear) != 1)
                {
                        
                }else
                    printf("The QUEUE is EMPTY. No orders to serve.\n");
                break;
            case 0:
                printf("\nOrder system has been terminated.\n");
                return 0;
            default:
                printf("Invalid choice.\n");
                break;
            
        }
    system("pause");
    system("cls");
    }
        
}

struct Node* Init()
{
    struct Node* q = (struct Node*)malloc(sizeof(struct Node));
    q->link = NULL;
    return q;
}

int Empty(struct Node* fr, struct Node* rr)
{
    if(fr == NULL && rr == NULL)
    {
        return 1;
    }else{
        return 0;
    }
}

struct Node* Front(struct Node* fr)
{
    return fr;
}

void AskOrder(struct Node** front, struct Node** rear)
{
    char name[MAXLENGTH];
    char order[MAXLENGTH];
    printf("\nWhat's your name? ");
    fflush(stdin);
    gets(name);
    printf("What's your order? ");
    fflush(stdin);
    gets(order);
    EnQueue(name, order, front, rear);
}

void EnQueue(char* nm, char* ordr, struct Node** fr, struct Node** rr)
{
    struct Node* temp = Init();
    strcpy(temp->name, nm);
    strcpy(temp->order, ordr);
    if(Empty(*fr, *rr) == 1)
    {
        *fr = *rr = temp;
        return;
    }
    (*rr)->link = temp;
    *rr = temp;
}

struct Node* DeQueue(struct Node** fr, struct Node** rr)
{
    struct Node* printme = *fr;
    struct Node* temp = *fr;
    if(*fr == *rr){
        *fr = *rr = NULL;
    }else{
        *fr = (*fr)->link;
    }
    free(temp);
    return printme;
}



void display(struct Node* fr){
    while(fr != NULL) 
    {
        printf("\n[%s] of customer [%s]", fr->order, fr->name);
        fr = fr->link;  
    }
}
smiili
  • 53
  • 5
  • Fyi, `fflush(stdin);` - don't do that. it's not only non-standard, it invokes *undefined behavior*. That's not how one "cleans" the input stream. And absolutely don't use `gets` ; it is so vile and evil it has been removed from the standard library, and should never be used. – WhozCraig Nov 19 '20 at 16:46
  • You have `scanf("%d", &ch);` but [scanf() leaves the newline char in the buffer](https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer). So the next `gets()` or `fgets()` reads an "empty string". – Weather Vane Nov 19 '20 at 16:57
  • @WhozCraig Umm, so what I use besides fflush(stdin)? I can't seem to find another way that I can comprehend – smiili Nov 19 '20 at 17:03
  • You shouldn't need to. If the input is redirected from a file, that would clean out the entire input anyway. Don't mix the input methods: either use `scanf()` or `fgets()` (possibly followed by `sscanf()` applied to the string). Using `scanf()`, newlines ane other whitespace are cleaned off automatically for most format specifiers (except `%c` and `%[]` and `%n`, when you can place a space in front, like `" %c"` to do the job). – Weather Vane Nov 19 '20 at 17:06
  • Related to your problem, your dequeue is freeing the node whose pointer is then returned to the caller, and subsequently dereferenced (thereby hitting up undefined behavior). That design is frankly questionable from the get-go. There's a reason why library implementations provide a "front" and a "pop" set of operations; its just easier. The former gives access to the head node of the queue, the latter disposes the node outright. If you want the node data, copy it from off from "front" *before* you pop. Academia often has "pop" operations return the node, but reality if often not as assumptive. – WhozCraig Nov 19 '20 at 17:11
  • Like... what library implementations? I'm new with this and their terms. – smiili Nov 19 '20 at 17:23
  • Well, the best example would be in C++ (the std::queue adapter), but just about any generic queue delivers similar functionality. Anyway, its something to consider. You'll find the code i just easier to understand too. – WhozCraig Nov 19 '20 at 17:26

0 Answers0