2017-02-02 3 views
-1

J'ai donc écrit un simple code C qui génère N membres de Fibonacci puis écrit chaque membre dans un nœud de liste chaînée puis écrit tout cela.Le code C simple ne fonctionne pas correctement quand le fichier input.txt lui est passé

Je code dans les fenêtres de Geany, mais j'ai testé le code dans ubuntu car gcc fonctionne bizarrement dans Windows. J'ai écrit le code, il compile les versions et les exécutions, quand j'introduis tout ce qui fonctionne, tout va bien. Par exemple l'entrée est 1 5 2 3. 1 est le choix du menu pour entrer le N nombre de membres, 5 est le nombre de membres que l'utilisateur choisit, 2 est pour générer les noeuds et l'écrire dans les noeuds et 3 est pour imprimer tout cela. Tout fonctionne bien et bien là, mais le problème est, quand je prends un fichier in.txt avec 1 5 2 3 écrit en elle et passe au code avec le chat in.txt | Commande ./fibonacci> out.txt dans Ubuntu, mon fichier out.txt est ÉNORME, avec beaucoup de sorties répétées. Si je viens d'entrer le numéro 3 directement, je reçois un message disant "La liste est vide", ce qui est bien. Mais quand j'entre seulement un nombre 3 dans mon fichier in.txt et exécute la commande je reçois 150 Mo de "la liste est vide" dans mon out.txt. Donc, quand je confie mon affectation à un vérificateur d'assignation automatisé, nous avons sur mon collège la même chose et l'affectation me donne un grand rouge non-non. Je ne comprends pas vraiment quel est le problème, pourquoi ai-je un programme fonctionnant parfaitement quand il est exécuté directement mais quand un fichier d'entrée lui est passé avec un seul numéro 3 j'obtiens des messages infinis "la liste est vide" comme ma sortie dans mon fichier out.txt.

Voici le code

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

#ifndef DEBUG 
#define DEBUG(...) printf(__VA_ARGS__) 
#endif 

typedef struct Node { 
    struct Node *next; 
    int val; 
} node; 

int entry() 
{ 
    int n; 
    scanf("%d", &n); 
    if(n <= 0) return -1; 

    return n; 

} 
int make_list (int val, node **head) 
{ 
    node *new, *current; 
    new=(node*) malloc(sizeof(node)); 
    if(!new) return -1; 

    new->val = val; 
    new->next=NULL; 

    if(!*head){ 
     *head = new; 
    }else { 
     for(current=*head; current->next != NULL; current= current->next); 
     current->next = new; 
    } 

return 0; 
} 

int fibonacci (int n, node **head){ 
    int i, f1=0, f2=1, next=0; 
    if (n <= 0) return -1; 
    for(i=1; i<n; i++){ 
    if(i==1){ 
     make_list(f1, head); 
     continue; 
    } 
    if(i==2){ 
     make_list(f2, head); 
     continue; 
    } 
    next = f1+f2; 
    f1=f2; 
    f2=next; 
    make_list(next, head); 
} 
return 1; 
} 

int print(node *head){ 
node *current; 

if(!head) return -1; 

for(current=head; current!=NULL; current=current->next){ 
    printf("%d ", current->val); 
} 
return 0; 
} 


int main(int argc, char **argv) 
{ 
node *head=NULL; 
char menu_choice; 
int retval, n; 

do { 
    DEBUG("\n(1) Enter number of Fibonacci members \n(2) Generate N numbers    of Fibonacci \n(3) Print out list \n(e) Exit\n"); 

    scanf(" %c", &menu_choice); 
    switch (menu_choice) { 
     case '1': 
      retval = entry(); 
      n = retval; 
      if (retval == -1) printf("You entered negative number\n"); 
      break; 
     case '2': 
      retval = fibonacci(n+1, &head); 
      if (retval==1) printf("Numbers are generated\n"); 
      if (retval==-1) printf("Not possible to generate numbers\n"); 
      break; 
     case '3': 
      retval = print(head); 
      if (retval==-1) printf("List is empty\n"); 
      break; 
    } 
} while(menu_choice!='e'); 





return 0; 

}

+0

Pourquoi votre txt ne contient pas la commande 'e'? Vous ne vérifiez pas le résultat de 'scanf', donc il continuera à boucler sur l'entrée qu'il n'a pas reçue. –

+0

Vous Monsieur ... Vous êtes mon sauveur Monsieur! : D – M4cX1

Répondre

1

Votre entrée ne contient pas la terminaison du programme g commande 'e'. En outre, vous ne vérifiez pas le résultat de scanf. Donc, ces deux en conjonction font votre programme à boucle infiniment avec la valeur périmée dans le menu_choice qui est '3' dans votre cas, en écrivant la sortie correspondante dans le fichier.

+0

Oui, Eugene m'a sauvé avec la partie e, mais qu'est-ce que vous les gars signifie avec je ne vérifie pas mon résultat scanf? Je veux dire maintenant je suis entré "e" à la fin de l'entrée dans mon fichier d'entrée et tout semble fonctionner. Dois-je faire quelque chose avec ce résultat scanf que vous mentionnez ou? Est-ce que c'est bien comme ça, après le "e" correctif? – M4cX1

+0

Vous feriez mieux de vérifier la valeur de retour de 'scanf' pour vous assurer que votre entrée ne se termine pas anormalement (comme dans votre cas).Il renvoie le nombre d'entrées renseignées. Donc si c'est "0", il n'a lu aucun caractère et vous devriez terminer (je suis le même Eugene, BTW :)). –

+0

Parlez-vous du scanf de la variable menu_choice ou du scanf de la variable N dans la fonction d'entrée? En tout cas, je ne suis pas vraiment sûr de savoir comment je devrais le vérifier. Voulez-vous dire quelque chose comme "if (! Menu_choice)" ou? – M4cX1

0

Vous ne semblez pas initialiser n dans tous les scénarios

Si vous écrivez 2 premier n est laissé non initialisée

node *head=NULL; 
char menu_choice; 
int retval, n;  <---- 

do { 
    DEBUG("\n(1) Enter number of Fibonacci members \n(2) Generate N numbers    of Fibonacci \n(3) Print out list \n(e) Exit\n"); 

    scanf(" %c", &menu_choice); 
    switch (menu_choice) { 
    case '1': 
     retval = entry(); 
     n = retval; 
     if (retval == -1) printf("You entered negative number\n"); 
     break; 
    case '2': 
     retval = fibonacci(n+1, &head); <-- n defined only if case 1: first 
     if (retval==1) printf("Numbers are generated\n"); 
     if (retval==-1) printf("Not possible to generate numbers\n"); 
     break; 
+0

Oui, ce "trou" est celui que je connais, mais je ne sais pas comment y remédier. Je ai essayé d'initialiser n à 0 au début, mais je reçois toujours "Les nombres sont générés" au lieu de "Non possible ...". Je ne sais pas pourquoi, mais c'est en fait moins un problème que la sortie infinie était. Des idées sur la façon dont je devrais traiter cette partie? – M4cX1

+0

@ M4cX1 tout d'abord se débarrasser de scanf pour lire à partir du clavier. à la place, utilisez fgets, puis lisez simplement le premier caractère du buffer. par exemple. le tampon char [32]; fgets (buffer, sizeof (buffer), stdin); ceci vous assurera que vous n'avez pas de \ n dans le stdin après avoir lu le caractère. ! 'Menu_choice = * buffer;' –

+0

@ M4cX1 initialize n à 0. check-in '2': si n = 0 si oui, alors appelez fibonacci autrement donner erreur –