tags:

views:

381

answers:

5

correction it works now thanks everyone.

Okay so now I have updated my main file to
main.c

#include "queue.h"

int main(){
    int i;
    int* dataPtr;
    int number;
    QUEUE* numbers;
    numbers = createQueue ();

    printf("Please enter the 10 numbers you want to know the sum and average of.\n");

    for (i = 0; i < 10; i++){
        printf("Number %d: ", i+1);
        scanf("%d", &number);
        *dataPtr = number;
        enqueue(numbers, dataPtr);
    }



  system("Pause");
  return 0;

}

But my program crashes when it is ran
Does anyone know why this is happening?

Original Post

I am having trouble figuring out how to fill a queue with user input in C. Can anyone point me in the right direction.

queue.h:

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

//Queue ADT Type Definitions
        typedef struct node{
                void* dataPtr;
                struct node* next;
        } QUEUE_NODE;

        typedef struct{
                QUEUE_NODE* front;
                QUEUE_NODE* rear;
                int count;
        } QUEUE;

//Prototype Declarations      
        QUEUE* createQueue (void);
        QUEUE* destroyQueue (QUEUE* queue);

        bool dequeue        (QUEUE* queue, void** itemPtr);
        bool enqueue        (QUEUE* queue, void*  itemPtr);
        bool queueFront     (QUEUE* queue, void** itemPtr);
        bool queueRear      (QUEUE* queue, void** itemPtr);
        int  queueCount     (QUEUE* queue);

        bool emptyQueue     (QUEUE* queue);
        bool fullQueue      (QUEUE* queue);
//End of Queue ADT definitions

Queue.c

#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
QUEUE* createQueue (void){
       QUEUE* queue;

       queue = (QUEUE*) malloc (sizeof (queue));
       if (queue){
          queue->front  = NULL;
          queue->rear   = NULL;
          queue->count  = 0;
       }
       return queue;
}

bool enqueue (QUEUE* queue, void* itemPtr){
     QUEUE_NODE* newPtr;

     if(!(newPtr = (QUEUE_NODE*)malloc(sizeof(QUEUE_NODE))))
                 return false;

     newPtr->dataPtr    = itemPtr;
     newPtr->next       = NULL;

     if (queue->count == 0)
         queue->front = newPtr;
     else
         queue->rear->next = newPtr;

     (queue->count)++;
     queue->rear = newPtr;
     return true;
}

bool dequeue (QUEUE* queue, void** itemPtr){
     QUEUE_NODE* deleteLoc;

     if (!queue->count)
        return false;

     *itemPtr  = queue->front->dataPtr;
     deleteLoc = queue->front;
     if(queue->count == 1)
         queue->rear  = queue->front = NULL;
     else
         queue->front = queue->front->next;
     (queue->count)--;
     free (deleteLoc);

     return true;
}

bool queueFront (QUEUE* queue, void** itemPtr){
     if (!queue->count)
        return false;
     else{
          *itemPtr = queue->front->dataPtr;
          return true;
     }
}

bool queueRear (QUEUE* queue, void** itemPtr){
     if (!queue->count)
        return true;
     else{
          *itemPtr = queue->rear->dataPtr;
          return false;
     }
}

bool emptyQueue (QUEUE* queue){
     return (queue->count == 0);
}

bool fullQueue(QUEUE* queue){
     QUEUE_NODE* temp;

     temp = (QUEUE_NODE*)malloc(sizeof(*(queue->rear)));
     if (temp){
               free (temp);
               return true;
               }
     return false;
}

int queueCount(QUEUE* queue){
    return queue->count;
}

QUEUE * destroyQueue (QUEUE* queue){
      QUEUE_NODE* deletePtr;

      if (queue){
                 while (queue->front != NULL){
                       free (queue->front->dataPtr);
                       deletePtr = queue->front;
                       queue->front = queue->front->next;
                       free(deletePtr);
                 }
                 free (queue);
      }
      return NULL;
}

main.c
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

int main(){
    int number;
    int *dataPtr;
    QUEUE* numbers;
    numbers = createQueue ();

    printf("Please enter the 10 numbers you want to know the sum and average of.\n");

    for (int i = 0, i < 10; i++){
        if (!(dataPtr = (int*) malloc (sizeof (int))))
           printf("Overflow trying to fill queues.\n"), exit(100);




  system("Pause");
  return 0;

}
+1  A: 

Judging from you comments, I assume the problem state is something like

Accept a sequence of numerically valued inputs from the user, and fill the queue with the results.

To do this you need to:

  • Loop over the input until some termination condition is met (the problem state probably says what to use, if not pick something that it is not possible to mistake for data (since the expected input is numeric, consider using a letter like 'q' to stop the input)).
  • For each input, get it (from the keyboard, from a file? You don't say), check to see if it is the terminating condition, and if not, convert to a numeric value.
  • Enqueue the result.

I can't be more helpful without a closer definition of the problem and a better indication of where you are stuck.


The queue that you are using appears to be implemented as a linked list, so you can walk the list by hand to non-destructively access the contents. That breaks the abstraction, but will work just fine.

Use ptr = queueFront() to get a pointer to the first node, then use ptr = ptr->next everytime you want to move to the next node. To access the payload of a single node get ptr->dataPtr and dereference (i.e. follow the pointer) that.

dmckee
well really now once I fill a queue is there a way to view each item or do I need to pull each item out and then put it back in to the end? The actually thing should get 10 numbers from the user(keyboard) insert in a queue the use those numbers for some math work. but the queue will have to be used multiple times so I cant delete or alter whats inside between math functions
shinjuo
If that's the case, then you shouldn't really be using a queue.
Anon.
@Anon: agreed, but if this is homework or a learning exercise, the OP may be stuck with the specification.
dmckee
I am using a queue because I am practicing queues and this is one of the stuff they suggest to try.
shinjuo
+1  A: 

I think you are looking for the gets() or ssscanf() functions to get user input from the console. The queue code looks ok, you just need to get integers from the console, then use your queue functions to perform the operations.

Jeff
+1  A: 

You have posted the interface to a general purpose queue facility. It looks like a perfectly reasonable queue facility to me. The facility lets you put items into the queue, ask simple questions of the queue (eg is the queue empty?), and take items from the queue. With queues the items come out on a FIFO (first in, first out) basis, just like people lining up in a physical queue. So normally you add new items to the queue's rear, whilst removing items from the queue's front.

From your comments, it sounds as if you are not concerned about initially populating the queue. Your problem is that you want to perform processing on each item in an existing queue without either adding or removing items. Some queue facilities let you iterate through the items currently in the queue so you can do that. But unfortunately I don't think your queue allows this. The clue is that the itemPtr parameter that receives the output of the queueFront() method ends up pointing not to a QUEUE_NODE but to void (i.e. arbitrary data). If this method let you see the QUEUE_NODE at the front of the queue, you could first look at the dataPtr of that QUEUE_NODE to examine the data, then look at the next pointer to look at the next QUEUE_NODE. But instead your facility is just showing you the data with no provision to find the data of the next QUEUE_NODE.

However this isn't a big problem. Simply take each item from the queue, process it, then immediately put it in a new queue. When you've looked at every item, your new queue will have the same elements in the same order as the original queue used to have, and the original queue will now be empty. In other words you'll still have one queue, containing the same items in the same order that you started with.

Edit I just realized refining this idea slightly avoids the need for a second queue. Simply remove each item in the queue, and after processing it, add it back to the same queue. That way, once every item has been processed the queue will be in its original state again, with the same items in the same order.

Bill Forster
I will try this as soon as I get this rest to work
shinjuo
+2  A: 

The type mismatch is here:

gets(number);

Two things wrong here:

  1. You are passing the wrong type (an int. gets() expects a char[].)
  2. You are passing it by value. It should be by reference (via a pointer.)

A more appropriate call would be:

scanf("%d", &number);

I could explain the "correct" use of gets(), but it is better not to use it at all. The Wikipedia page explains why.


I think there is another bug here: dataPtr is uninitialised. Try this:

    scanf("%d", &number);
    dataPtr = malloc(sizeof(int));
    *dataPtr = number;
finnw
I changed it, but now the program does not even run.
shinjuo
shinjuo
In this context it is the "address of" operator which returns a pointer to the (single) argument. Supported by both. Note that this use is (just slightly) different from the "reference" operator in c++ which looks exactly the same.
dmckee
+1  A: 

Apparently you have not allocated memory for dataPtr before "*dataPtr = number;" as finnw pointed out. I have your program running fine in gcc just by changing the above.

csk