Problèmes de saisie de caractères avec scanf ()

J’essaie de saisir un caractère dans une liste chaînée, le caractère pouvant être “A”, “a”, “G”, “g”, “T”, “t”, “C” ou “c”.

Je ne suis pas encore familier avec C et je sais que j’ai foutu quelque chose ici:

do{ printf ("\nEnter a new nucleotide: \n"); scanf("%c",&newChar); /* Checking */ if(newChar == 'A' || newChar == 'a' || newChar == 'G' || newChar == 'g' || newChar == 'T' || newChar == 't' || newChar == 'C' || newChar == 'c' ) { AddToSequence(newChar); size++; } else { printf ("\nBad Element"); } }while(newChar != 'x'); 

newChar est initialisé avec une valeur indésirable, dans ce cas ‘q’.

La saisie de ‘x’ ferme la boucle, la saisie de toute valeur acceptable appelle AddToSequence (), et toute valeur inacceptable reçoit un avertissement.

Pour une raison quelconque, quelle que soit la valeur de newChar, elle passera à l’autre. Il sautera également directement devant le scanf sans attendre l’entrée de l’utilisateur et effectuera deux boucles à chaque fois. Quelqu’un peut-il me dire où je vais mal?

Programme complet:

 #include #include /*Structure declaration for the node*/ struct node{ char nucleotide; struct node *point; }*start; /* Adds a nucleotide to the chain. Creates a new linked list if no chain exists exists.*/ void AddToSequence(char nucleotide){ struct node *loc, *first; //Dynamic memory is been allocated for a node first=(struct node*)malloc(sizeof(struct node)); first->nucleotide=nucleotide; first->point=NULL; if(start==NULL){ /*If list is empty*/ start=first; }else{ /*Element inserted at the end*/ loc=start; while(loc->point!=NULL){ loc=loc->point; loc->point=first; } } } /* Display elements */ void Display(){ struct node *loc; if(start == NULL){ printf ("\n\nList is empty"); return; } loc=start; printf("\n\nList is : "); while(loc!=NULL){ printf ("%c", loc->nucleotide); loc=loc->point; } printf ("\n"); } /* Finds and displays percentage of the chain made up of each nucleotide. */ void Percentage(int size){ struct node *loc; if(start == NULL){ printf ("\n\nList is empty"); return; } loc=start; printf("\n\nList is : "); int A = 0, G =0, T =0, C = 0; double Adouble = 0, Gdouble =0, Tdouble=0, Cdouble=0; while(loc!=NULL){ if(loc->nucleotide=='A' || 'a'){A++;} if(loc->nucleotide=='G' || 'g'){G++;} if(loc->nucleotide=='T' || 't'){T++;} if(loc->nucleotide=='C' || 'c'){C++;} loc=loc->point; } printf ("\n"); /* Convert to double for percentages as int loses precision */ Adouble =A; Gdouble =G; Tdouble =T; Cdouble =C; Adouble =(Adouble/size)*100; Gdouble =(Gdouble/size)*100; Tdouble =(Tdouble/size)*100; Cdouble =(Cdouble/size)*100; printf("\nA: %f", Adouble); printf("\nG: %f", Gdouble); printf("\nT: %f", Tdouble); printf("\nC: %f", Cdouble); } /* There be dragons beyond here */ int main(){ int navigate, size =0; char newChar = 'q'; do{ /* Menu */ printf("\n 1. Create / Extend Sequence\n"); printf("\n 2. Display Sequence\n"); printf("\n 3. Count \n"); printf("\n 0. Exit \n"); printf("\nPlease select an option (0 to 3)\n"); scanf("%d",&navigate); switch (navigate){ case 0: /* Exit */ break; case 1: /* Add nucleotides */ do{ printf ("\nEnter a new nucleotide: \n"); scanf("%c",&newChar); /* Some error checking */ if(newChar == 'A' || newChar == 'a' || newChar == 'G' || newChar == 'g' || newChar == 'T' || newChar == 't' || newChar == 'C' || newChar == 'c' ){ AddToSequence(newChar); size++; } else { printf ("\nBad Element"); } }while(newChar != 'x'); break; case 2: Display(); break; case 3: Percentage(size); break; default: printf ("\n\nBad choice. Please select another.\n"); } } while (navigate !=0); return 0 ; } 

Vous ne gérez pas la nouvelle ligne. Le spécificateur %c n’ignore pas les blancs. Essayer:

 scanf(" %c", &newChar); /* ^ <-- Makes `scanf` eat the newline. */ 

Ou peut-être append un test explicite.

 scanf(...); if (newChar == '\n') continue; 

ajoutez un espace à "%c" pour intercepter le caractère de nouvelle ligne. le caractère d’espace est utilisé pour capturer des espaces, des tabulations, des nouvelles lignes

 scanf("%c ",&newChar); 

Vous quittez le '\n' sur stdin :

 scanf("%d",&navigate); getchar(); // consume the newline character ... scanf("%c",&newChar); getchar(); // consume the newline character 

Ou, puisque vous utilisez déjà scanf() vous pouvez demander à scanf de s’occuper du caractère de nouvelle ligne:

 scanf("%d\n", &navigate); .... scanf("%c\n",&newChar); 

Mieux encore, vous pouvez le laisser ouvert en ajoutant un espace après le spécificateur de format:

 scanf("%d ", &navigate); .... scanf("%c ",&newChar); 

Juste au cas où l’utilisateur voudrait faire quelque chose comme: 2

Quelle que soit la façon dont vous le gérez, le fait est que vous devez utiliser le caractère de nouvelle ligne.

Utilisation

 newChar=getche(); 

Il s’agit d’une fonction non standard qui récupère un caractère du clavier et renvoie à l’écran.