问题
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:
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.
There are many queues, there are fifo, lifo, and depending on it you choose how to build it
When dealing with queues, it's better to use function names like
push
,pop
andtop
because they are widely used among other programmers and queue libraries. Use these names instead.In your case, instead if remembering with
front
andrear
you should usememmove
instead and use a variablelen
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