1
votes

tandis que le code de boucle ne fonctionne pas (continue = 'y')

J'apprends donc à utiliser les boucles while et for en C mais ce code ne semble pas fonctionner. l'instruction scanf semble être ignorée et la boucle se répète sans me demander d'entrer «Y» pour qu'elle se répète. Voici le code:

Enter the amount of sales                                                                         
5000                                                                                              
The commission is $500.000000.                                                                    
Do you want to calclulate another?    

...Program finished with exit code 10                                                             
Press ENTER to exit console.  

Voici ce que l'exécution du code me donne:

void showCommission();

void main() {
    char keepGoing='y';
    while(keepGoing=='y') {
        showCommission();
        printf("Do you want to calculate another?\n");
        scanf("%c",&keepGoing);
   }
}

void showCommission() {
    float sales,commission;
    const float COM_RATE=0.10;
    printf("Enter the amount of sales\n");
    scanf("%f",&sales);
    commission=sales*COM_RATE;
    printf("The commission is $%f.\n",commission);
}

cela ne m'invite jamais à entrer y et le code sort juste pour une raison quelconque.


2 commentaires

Essayez cette question pour voir si elle aide à expliquer pourquoi vous voyez ce problème.


OT: void le type de retour de main () n'est pas conforme aux normes. Le type de retour de main () doit être int .


3 Réponses :


-1
votes

Ceci est dû au retour à la ligne (entrée de touche) restante de l'entrée non-caractère. scanf("%f",&sales);

Par exemple, si je saisis 500 pour le montant des ventes, le programme lira 500 \ n, où \ n est votre touche de saisie. Cependant, scanf ("% f", & sales) ne lira que la valeur flottante. Par conséquent, le \ n est resté dans votre tampon d'entrée. Ensuite, lorsque le programme essaie d'exécuter scanf ("% c", & keepGoing), il consomme les restes \ n et il traitera lorsque vous avez appuyé sur la touche Entrée et ignoré l'entrée.

Le problème peut être résolu en consommant les restes \ n.

void showCommission() {
float sales,commission;
char consumeNewLine;
const float COM_RATE=0.10;
printf("Enter the amount of sales\n");
scanf("%f",&sales);
scanf("%c",&consumeNewLine);
commission=sales*COM_RATE;
printf("The commission is $%f.\n",commission);
}


2 commentaires

cela ne répond pas du tout à la question.


Ma faute. Je n'ai pas lu la question correctement. Édité avec une nouvelle réponse.



11
votes

Le problème que vous rencontrez est que l'appel à scanf pour lire une valeur au format % c acceptera une nouvelle ligne caractère comme entrée valide!

Ceci, combiné avec le fait que l'appel scanf ("% f", & sales); lit une valeur float mais ne «consomme» pas la nouvelle ligne suivante, laissera ce caractère de nouvelle ligne dans la mémoire tampon d'entrée, pour que l'appel suivant lise une valeur pour keepGoing . Ainsi, vous aurez une valeur pour keepGoing qui n'est pas y et le programme se terminera.

Il y en a plusieurs moyens de contourner cela. Le plus simple, peut-être, est d'ajouter un caractère espace avant le champ % c , ce qui demandera à la fonction scanf d'ignorer tous les caractères «espace» (qui inclut le retour à la ligne) lors de la «recherche» du caractère d'entrée:

scanf(" %c", &keepGoing); // Added space before %c will skip any 'leftover' newline!


0 commentaires

4
votes

Vous avez quelques problèmes. Tout d'abord, vous devez vérifier vos valeurs de retour scanf ; si stdin est fermé sans fournir y , scanf retournera constamment -1 sans réécrire keepGoing code> (rendant la boucle infinie).

L'autre problème est la sortie précoce; % c supprime le comportement normal de saut d'espaces scanf , ainsi vos scanf dans main essaient toujours de lire tout ce qui a suivi le flottant que vous venez d'analyser pour renseigner ventes (généralement des espaces ou une nouvelle ligne), donc lorsque vous entrez:

if (scanf(" %c", &keepGoing) != 1) break;

le % c

lit la nouvelle ligne après le 2, pas le y , et la boucle se termine immédiatement.

Une solution simple serait de changer: p >

scanf("%c",&keepGoing);

à:

1.12
y

L'espace de début réactivera le saut d'espaces afin qu'il consomme tous les espaces avant d'essayer de lire le caractère suivant, et chaque fois qu'il ne parvient pas du tout à lire un caractère, il mettra fin à la boucle, plutôt que de courir pour toujours. Une vérification similaire devrait probablement être ajoutée pour votre autre scanf.


2 commentaires

Il pouvait également lire deux caractères. Déclarez char discardNL; puis scanf ("% c% c", & keepGoing,% discardNL);


@JoelTrauger: Cela suppose que l'utilisateur n'a pas accidentellement entré un petit espace blanc de fin sur la ligne précédente, ou appuyez deux fois sur Entrée ou autre. Sauter tous les espaces, même s'il y en a, est généralement mieux (bien sûr, encore mieux serait de valider correctement l'entrée, de supprimer les lignes lorsque l'analyse des flottants ne fonctionne pas, forçant l'entrée à continuer à être uniquement y ou n et repromptage quand ce n'est pas le cas et que stdin n'a pas atteint EOF, etc.).