2010-02-08 7 views
0

Cela doit être très simple mais étant donné que je viens du monde de Java, je me sens un peu dans les bois dans ce cas.Pourquoi scanf ne bloque pas le thread pour l'entrée dans ce cas? Objective-C

while (operator != 'E') { 
    NSLog(@"Enter:"); 
    scanf("%lf %c", &value2, &operator); 

    switch (operator) { 
    case 'S': 
    [deskCalc setAccumulator:value2]; 
    break; 
    case 'E': 
    break; 
    case '+': 
    [deskCalc add:value2]; 
    break; 
    case '-': 
    [deskCalc subtract:value2]; 
    break; 
    case '/': 
    [deskCalc divide:value2]; 
    break; 
    case '*': 
    [deskCalc multiply:value2]; 
    break; 
    default: 
    NSLog(@"Unknown command"); 
    break; 
    } 

    NSLog(@"=%g", [deskCalc accumulator]); 

} 

Maintenant, si je rentre juste « e » ou d'autres caractères sans entrer dans le premier numéro du programme passe en boucle comme ceci:

2010-02-08 13:44:38.690 Calculator[89939:a0f] Enter: 
2010-02-08 13:44:38.691 Calculator[89939:a0f] Unknown command 
2010-02-08 13:44:38.691 Calculator[89939:a0f] =10 
2010-02-08 13:44:38.692 Calculator[89939:a0f] Enter: 
2010-02-08 13:44:38.692 Calculator[89939:a0f] Unknown command 
2010-02-08 13:44:38.693 Calculator[89939:a0f] =10 

Pourquoi scanf ne bloque pas le fil et demander entrée correcte à nouveau?

Merci Noi

Répondre

2

Ce n'est pas un problème, mais un problème ObjC C.

Le problème ne bloque pas le thread. Dans votre scanf, vous demandez un nombre à virgule flottante (%lf) suivi de quelques espaces (), puis un caractère (%c). Mais lorsque vous entrez e, ce n'est pas un nombre à virgule flottante valide, donc scanf échoue immédiatement.

Mais le caractère non valide e est toujours laissé dans le tampon . Ainsi, dans l'opération suivante avec stdin, vous demandez à nouveau un nombre à virgule flottante, et il échoue et revient immédiatement car e n'est toujours pas valide, puis le scanf suivant demande de nouveau un numéro de pointeur flottant, ad infinitum.

Voir Why is scanf() causing infinite loop in this code? pour les détails.

L'alternative plus sûre est d'utiliser fgets pour lire l'entrée brute, puis analyser la chaîne reçue pour obtenir value2 et operator.

+0

Donc, si scanf échoue une fois, il ne peut plus fonctionner avec les mêmes variables? Si la correspondance échoue, la boucle while devient infinie car scanf ne bloque pas pour l'entrée de l'utilisateur. Ça bousille quelque chose sous le capot, je suppose. Et je veux comprendre quoi exactement. –

+0

@noi: Voir mise à jour. – kennytm

+0

Merci, KennyTM, tout est clair maintenant. –