2009-10-13 9 views
4

Lors de la programmation C pour la console de commande, ce qui se passe lorsque vous avez une fonction qui tente d'utiliser Scanf pour demander l'entrée d'utilisateur pour une variable CHAR, et les types d'utilisateurs CTRL + Z (EOF) et frappe frappe?C Programmation: EOF comme caractère

Par exemple:

char promptChar() 
{ 
    char c; 
    printf("Enter a character: "); 
    scanf("%c", &c); 
    return c; 
} 

Si les types d'utilisateurs CTRL +Z et frappe entrer, ce sera PromptChar() retour? Parce que si je comprends EOF, c'est un int.

Répondre

11

Pour commencer:

SCANF n'est pas défini par la langue.
CHAR n'est pas défini par le langage.

Ok, avec celle de la route ...

La fonction scanf() renvoie un entier. Cet entier est le nombre d'éléments d'entrée affectés ou la valeur de la macro EOF si une défaillance d'entrée se produit avant la première conversion.
Vous n'avez pas vérifié la valeur de retour de l'appel scanf(), vous n'avez donc aucune idée de ce qui s'est passé. Tout a peut-être bien fonctionné, ou le flux d'entrée peut s'être arrêté avant la première conversion, ou (pas pour% c) il peut y avoir eu un échec de conversion.

Tester la valeur de retour de scanf(). En effet, teste toujours la valeur de retour de toutes les fonctions <stdio.h>.

char ch; 
int result = scanf("%c", &ch); 
if (result == 1) /* all ok */; 
else if (result == 0) /* conversion failure: value of `ch` is indeterminate */; 
else if (result == EOF) /* input failure; value of `ch` is indeterminate */; 

Lorsque le résultat de l'appel scanf() est EOF, si vous voulez plus d'informations sur la raison de l'échec d'entrée, vous pouvez utiliser feof() et/ou ferror().

else if (result == EOF) { 
    if (feof(stdin)) { 
     /* no data in input stream */ 
    } 
    if (ferror(stdin)) { 
     /* error if input stream (media ejected? bad sector? ...?) 
    } 
} 

Pour répondre à votre question: what will promptChar() return?

Il retournera une valeur indéterminée de type char.
Vous pouvez suivre l'exemple de la fonction de bibliothèque qui gère les caractères et renvoie un int de promptChar(). Ce serait la valeur du caractère lu à unsigned char ou un int négatif (EOF) en cas d'erreur. Lire la description pour fgetc(), par exemple.

+0

En outre, dans l'exemple, la valeur de retour sera indéterminée car il renvoie une variable locale. –

+2

@Patrice: pas vraiment, la valeur de 'c' est renvoyée pas' c' elle-même ou son adresse. Des problèmes de retour des variables locales se produisent lorsque vous leur renvoyez des pointeurs. – pmg

+1

"Toujours tester la valeur de retour de toutes les fonctions " -Je ne suis pas d'accord. Allez-vous vérifier la valeur de retour et 'errno' chaque fois que vous appelez' printf'? C'est trop pour moi. Vous ne serez pas capable de faire beaucoup de choses utiles si de simples sorties comme ça échouent. – mk12

4

De Linux scanf(3) manpage:.

« La valeur EOF est renvoyée si la fin de l'entrée est atteinte avant la première conversion réussie ou un échec correspondant se produit EOF est également renvoyée si une lecture une erreur se produit, auquel cas l'indicateur d'erreur du flux (voir ferror(3)) est défini et un numéro d'erreur indique l'erreur. "

Notez que ce passage concerne la valeur de retour de scanf, pas les paramètres de résultat.

-1

Cela dépend de l'interpréteur de commandes que vous utilisez, mais vous ne devriez pas concevoir de programme pour espérer lire des caractères de contrôle à partir d'une invite interactive.

La plupart des shells de commande intercepteront certains des caractères de contrôle et les utiliseront pour indiquer au shell de faire les choses. Par exemple, ctrl-s et ctrl-q démarrent et arrêtent souvent l'affichage du shell des caractères de sortie. ctrl-z sur certains shells sera en fait pris comme une commande pour fermer le shell.

+0

EOF n'est pas un caractère de contrôle. Ce n'est pas du tout un octet du flux - c'est une valeur * en dehors de la plage des caractères valides (par convention c'est 0xffffffff sur la plupart des plateformes) qui est retournée lorsque l'appel système sous-jacent signale la fin du fichier. –

+0

@Andy: EOF se produit lorsqu'un read() sur le fichier renvoie zéro octet de données. Lorsque vous tapez Control-D (ou Control-Z) sur le terminal, il envoie les caractères en attente aux programmes qui lisent depuis le terminal. S'il n'y a pas de caractères en attente, read() renvoie 0, ce qui est interprété comme EOF. Et EOF est -1 sur presque toutes les plates-formes; ce n'est pas 0xFFFFFFFF sur les plates-formes 64 bits. –

+0

Jonathan: Je sais. Je pense que vous êtes tout à fait d'accord avec moi. Qu'est-ce que EOF ** n'est pas ** est un "caractère de contrôle". Ça ne fait pas partie du courant. Et j'ai dit "la plupart" des plates-formes, donc je ne comprends pas le nit. Je l'ai écrit en hexagone pour rendre le fait que ce n'est pas un personnage clair. –