Making a queue program

时光总嘲笑我的痴心妄想 提交于 2019-12-25 05:19:09

问题


Can someone help me making a queue program. I want to set the array[0] to be array[1] just in display but in real I am adding value at array[0]. I got how to run the add function to it, but I can't do the view and delete command that will view from ex. array[0] to array[4], when displayed array[1] to array[5] with the value inserted.

#include <stdio.h>
#include <stdlib.h>
#define p printf
#define s scanf

int rear = 0;
int front = 0;
int *q_array = NULL;
int size = 0;

main()
{
    int num, opt;
    char cont[] = { 'y' };
    clrscr();
    p("Queue Program\n\n");
    p("Queue size: ");
    s("%d", &size);
    p("\n");

    if(size > 0)
    {
        q_array = malloc(size * sizeof(int));
        if(q_array == NULL)
        {
            p("ERROR: malloc() failed\n");
            exit(2);
        }
    }
    else
    {
        p("ERROR: size should be positive integer\n");
        exit(1);
    }

while((cont[0] == 'y') || (cont[0] == 'Y'))
{
    clrscr();
    p("Queue Program");
    p("\n\nQueue size: %d\n\n", size);
    p("MAIN MENU\n1. Add\n2. Delete\n3. View");
    p("\n\nYour choice: ");
    s("%d", &opt);
    p("\n");

    switch(opt) {
        case 1:
            if(rear==size)
            {
                p("You can't add more data");
            }
            else
            {
                p("Enter data for Queue[%d]: ", rear+1);
                s("%d", &num);
                add(num);
            }
            break;
        case 2:
            delt();
            break;
        case 3:
            view();
            break;
    }
    p("\n\nDo you want to continue? (Y\/N)");
    s("%s", &cont[0]);
}
}
add(int a)
{
    q_array[rear]=a;
    rear++;
}
delt()
{
    if(front==rear)
    {
        p("Queue Empty");
    }
    else
    {
        p("Queue[%d] = %d removed.", front, q_array[front]);
        front++;
    }
}
view()
{
    int i;
    for(i=front;i<=rear;i++)
        p("\nQueue[%d] = %d", i, q_array[i]);
}

回答1:


  1. One serious problem here is

    char cont[] = { 'y' };
    ...
    s("%s", &cont[0]);
    

    You've only reserved one byte but scanf will write at least 2 bytes, meaning that you are going to have a buffer overflow and then the overall behaviour is unpredictable. If you want to read a single character then use"%c" as a pattern but the problem here is that characters will be in the buffer for the next read, so you are going to have to clear the buffer.

    It's much easier to do:

    char line[1024];
    fgets(line, sizeof line, stdin);
    if(line[strlen(line)-1] == '\n')
        line[strlen(line)-1] = 0;
    
    if(strcmp(line, "Y") == 0 || strcmp(line, "y")==0)
    

    It's a little more code but it's safer this way.

  2. There are many queues, there are fifo, lifo, and depending on it you choose how to build it

  3. When dealing with queues, it's better to use function names like push, pop and top because they are widely used among other programmers and queue libraries. Use these names instead.

  4. In your case, instead if remembering with front and rear you should use memmove instead and use a variable len to count the current number of elements in the node. Once you've popped one element, you gained new space for more elements.

Also, try to use fewer global variables and more encapsulation: (in my example I am not going to care about malloc returning NULL, I want to keep it short)

#include <string.h> /* for size_t */

typefed struct {
    size_z len;
    size_z max_size;
    int    *data;
} queue;

void queue_init(queue *q, size_t max_size)
{  
    q->len      = 0; 
    q->max_size = max_size;
    q->data     = malloc(max_size * sizeof *(q->data));
    /* this is a good trick!
     * If you need to change the datatype of 'data',
     * you only need to change the definition of it.
     * This code is valid for any type */ 
}  

int push(queue *q, int data)
{  
    if(q->len == q->max_size)
        return 0; /* not enough space */ 

    q->data[q->len++] = data;
    return 1;
}

int top(queue *q, int *data)
{
    if(q->len == 0)
        return 0; /* no elements in the queue */
    *data = q->data[0];
    return 1;
}

int pop(queue *q, int *data)
{
    if(top(q, data) == 0)
        return 0;

    memmove(q->data, q->data + sizeof *(q->data), q->len--);
    return 1;
}

BTW:

#define p printf
#define s scanf

Just like Daniel Fischer said, this is ugly; don't do that.



来源:https://stackoverflow.com/questions/12652918/making-a-queue-program

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!