2010-02-14 6 views
2

correction cela fonctionne maintenant merci à tous.Remplir une file d'attente avec C

Ok maintenant je l'ai mis à jour mon dossier principal
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; 

} 

Mais mon programme se bloque quand il est couru
Est-ce que quelqu'un sait pourquoi cela se passe?

Original Post

Je ne parviens pas à trouver comment remplir une file d'attente avec l'entrée d'utilisateur en C. Quelqu'un peut-il me diriger dans la bonne 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; 

} 
+0

Tout exemple de code que vous avez serait utile :) – Jedidja

+0

Comment publiez-vous avec des balises de code? – shinjuo

+1

Je veux dire comment publiez-vous un bloc de code? – shinjuo

Répondre

2

L'incompatibilité de type est ici:

gets(number); 

Deux mauvaises choses ici:

  1. Vous passez le mauvais type (. Un intgets() attend un char[].)
  2. Vous passez en valeur. Il devrait être par référence

Un appel plus approprié serait (au moyen d'un pointeur.):

scanf("%d", &number); 

je pourrais expliquer l'utilisation « correcte » de gets(), mais il est préférable de ne pas utiliser du tout. Le Wikipedia page explique pourquoi.


Je pense qu'il ya un autre bug ici: dataPtr est uninitialised. Essayez ceci:

scanf("%d", &number); 
    dataPtr = malloc(sizeof(int)); 
    *dataPtr = number; 
+0

Je l'ai changé, mais maintenant le programme ne fonctionne même pas. – shinjuo

+0

est-ce que C supporte et/ou est-ce que C++ – shinjuo

+0

Dans ce contexte c'est l'opérateur "adresse de" qui retourne un pointeur vers l'argument (unique). Soutenu par les deux. Notez que cette utilisation est (légèrement) différente de l'opérateur "référence" en C++ qui ressemble exactement à la même chose. – dmckee

1

A en juger par vous des commentaires, je suppose que l'état du problème est quelque chose comme

Accepter une séquence de numériquement une valeur entrées de l'utilisateur, et remplir la file d'attente avec les résultats.

Pour ce faire, vous devez:

  • Boucle sur l'entrée jusqu'à ce qu'une condition de terminaison soit atteint (l'état du problème dit probablement ce qu'il faut utiliser, sinon choisir quelque chose qu'il est impossible de se tromper pour les données (puisque l'entrée attendue est numérique, pensez à utiliser une lettre comme 'q' pour arrêter l'entrée)).
  • Pour chaque entrée, l'obtenir (à partir du clavier, à partir d'un fichier? Vous ne dites pas), vérifier pour voir si c'est la condition de fin, et sinon, convertir en une valeur numérique.
  • Enqueue le résultat.

Je ne peux pas être plus utile sans une définition plus du problème et une meilleure indication de l'endroit où vous êtes coincé.


La file d'attente que vous utilisez semble être mis en œuvre comme une liste chaînée, de sorte que vous pouvez marcher la liste à la main pour accéder non destructive du contenu. Cela rompt l'abstraction, mais cela fonctionnera très bien. Utilisez ptr = queueFront() pour obtenir un pointeur vers le premier noeud, puis utilisez ptr = ptr->next chaque fois que vous souhaitez passer au noeud suivant. Pour accéder à la charge utile d'un seul nœud, obtenez ptr->dataPtr et déréférencer (c'est-à-dire suivre le pointeur).

+0

Eh bien maintenant, une fois que je remplis une file d'attente, est-ce qu'il y a un moyen de voir chaque élément ou dois-je sortir chaque élément et le remettre à la fin? La chose réelle devrait obtenir 10 numéros de l'utilisateur (clavier) insérer dans une file d'attente l'utilisation de ces chiffres pour certains travaux mathématiques. mais la file d'attente devra être utilisée plusieurs fois donc je ne peux pas supprimer ou modifier ce qui se trouve entre les fonctions mathématiques – shinjuo

+0

Si c'est le cas, alors vous ne devriez pas vraiment utiliser une file d'attente. –

+0

@Anon: d'accord, mais s'il s'agit de devoirs ou d'un exercice d'apprentissage, le PO peut être bloqué avec la spécification. – dmckee

1

Je pense que vous recherchez les fonctions gets() ou ssscanf() pour obtenir des entrées utilisateur depuis la console. Le code de la file d'attente semble correct, vous avez juste besoin d'obtenir des entiers de la console, puis utilisez vos fonctions de file d'attente pour effectuer les opérations.

1

Vous avez enregistré l'interface dans une fonction de file d'attente à usage général. Cela ressemble à une installation de file d'attente parfaitement raisonnable pour moi.L'installation vous permet de mettre des éléments dans la file d'attente, de poser des questions simples sur la file d'attente (par exemple, la file d'attente est-elle vide?) Et de retirer des éléments de la file d'attente. Avec les files d'attente, les éléments sortent sur une base FIFO (premier entré, premier sorti), tout comme les gens alignés dans une file d'attente physique. Donc, normalement, vous ajoutez de nouveaux éléments à l'arrière de la file, tout en supprimant les éléments du front de la file d'attente. De vos commentaires, il semble que vous ne soyez pas préoccupé par le remplissage initial de la file d'attente. Votre problème est que vous souhaitez effectuer un traitement sur chaque élément dans une file d'attente existante sans ajouter ou supprimer des éléments. Certaines fonctionnalités de file d'attente vous permettent de parcourir les éléments actuellement dans la file d'attente afin que vous puissiez le faire. Mais malheureusement, je ne pense pas que votre file d'attente le permette. L'indice est que le paramètre itemPtr qui reçoit la sortie de la méthode queueFront() finit par pointer non pas sur un QUEUE_NODE mais sur void (c'est-à-dire des données arbitraires). Si cette méthode vous permet de voir le QUEUE_NODE au début de la file d'attente, vous pouvez d'abord regarder le dataPtr de ce QUEUE_NODE pour examiner les données, puis regarder le pointeur suivant pour regarder le prochain QUEUE_NODE. Mais au lieu de cela votre installation vous montre simplement les données sans aucune provision pour trouver les données du prochain QUEUE_NODE.

Cependant, ce n'est pas un gros problème. Prenez simplement chaque élément de la file d'attente, traitez-le, puis mettez-le immédiatement dans une nouvelle file d'attente. Lorsque vous avez examiné chaque élément, votre nouvelle file d'attente aura les mêmes éléments dans le même ordre que la file d'attente d'origine et la file d'attente d'origine sera vide. En d'autres termes, vous aurez toujours une file d'attente, contenant les mêmes éléments dans le même ordre que vous avez commencé.

Édition Je viens de réaliser que l'affinement de cette idée évite légèrement la nécessité d'une deuxième file d'attente. Retirez simplement chaque élément de la file d'attente et, après l'avoir traité, ajoutez-le à la même file d'attente. De cette façon, une fois que chaque élément a été traité, la file d'attente sera de nouveau dans son état d'origine, avec les mêmes éléments dans le même ordre.

+0

Je vais essayer cela dès que je reçois ce repos pour travailler – shinjuo

1

Apparemment, vous n'avez pas alloué de mémoire pour dataPtr avant "* dataPtr = nombre;" comme l'a souligné finnw. J'ai votre programme fonctionne bien dans gcc juste en changeant ce qui précède.