web-dev-qa-db-fra.com

Représentant EOF en code C?

Le caractère de nouvelle ligne est représenté par "\n" en code C. Existe-t-il un équivalent pour le caractère de fin de fichier (EOF)?

36
static_rtti

EOF n'est pas un personnage (dans la plupart des systèmes d'exploitation modernes). Il s'agit simplement d'une condition qui s'applique à un flux de fichiers lorsque la fin du flux est atteinte. La confusion survient car un utilisateur peut signal EOF pour l'entrée de la console en tapant un caractère spécial (par exemple Control-D sous Unix, Linux, et al), mais ce caractère n'est pas vu par le programme en cours d'exécution, il est capté par le système d'exploitation qui à son tour signale EOF au processus).

Remarque: dans certains systèmes d'exploitation très anciens EOF était un caractère, par exemple Control-Z dans CP/M, mais c'était un hack grossier pour éviter les frais généraux de maintenance longueurs réelles des fichiers dans les répertoires du système de fichiers.

62
Paul R

Non. EOF n'est pas un caractère, mais un état du descripteur de fichier.

Bien qu'il existe des caractères de contrôle dans le jeu de caractères ASCII qui représente la fin des données, ils ne sont pas utilisés pour signaler la fin des fichiers en général. Par exemple EOT (^ D) qui dans certains cas signale presque la même chose.

Lorsque la bibliothèque C standard utilise un entier signé pour renvoyer des caractères et utilise -1 pour la fin du fichier, ce n'est en fait que le signal pour indiquer qu'une erreur s'est produite. Je n'ai pas la norme C disponible, mais pour citer SUSv3:

Si l'indicateur de fin de fichier pour le flux est défini, ou si le flux est en fin de fichier, l'indicateur de fin de fichier pour le flux doit être défini et fgetc () doit retourner EOF. Si une erreur de lecture se produit, l'indicateur d'erreur pour le flux doit être défini, fgetc () doit retourner EOF et définir errno pour indiquer l'erreur.

7
pmakholm

EOF n'est pas un caractère. Cela ne peut pas être: un fichier (binaire) peut contenir n'importe quel caractère. Supposons que vous ayez un fichier avec des octets toujours croissants, allant de 0 1 2 3 ... 255 et de nouveau 0 1 ... 255, pour un total de 512 octets. Quel que soit l'un de ces 256 octets possibles que vous estimez EOF, le fichier sera raccourci.

C'est pourquoi getchar() et al. retourne un int. La plage de valeurs de retour possibles est celle qu'un char peut avoir, plus une véritable int valeur EOF (définie dans stdio.h). C'est aussi pourquoi la conversion de la valeur de retour en char avant la vérification de EOF ne fonctionnera pas.

Notez que certains protocoles ont des caractères "EOF" "." ASCII a "Fin de texte", "Fin de transmission", "Fin de bloc de transmission" et "Fin de support". D'autres réponses ont mentionné d'anciens systèmes d'exploitation. Je sais moi-même ^ D sous Linux et ^ Z sur les consoles Windows pour cesser de donner des entrées aux programmes. (Mais les fichiers lus via des canaux peuvent avoir des caractères ^ D et ^ Z n'importe où et ne signalent EOF qu'ils manquent d'octets).) Les chaînes C se terminent par le '\0' caractère, mais cela signifie également qu'ils ne peuvent pas contenir le caractère '\0'. C'est pourquoi toutes les fonctions de données non-chaîne C fonctionnent en utilisant un tableau char (pour contenir les données) et un size_t (pour savoir où se terminent les données).

Edit: La norme C99 §7.19.1.3 stipule:

Les macros sont [...]
EOF
qui se développe en une expression constante entière, de type int et une valeur négative, qui est renvoyée par plusieurs fonctions pour indiquer la fin du fichier , c'est-à-dire qu'il n'y a plus d'entrée d'un flux;

6
aib

J'ai lu tous les commentaires. Il est intéressant de noter ce qui se passe lorsque vous imprimez ceci:

printf("\nInteger =    %d\n", EOF);             //OUTPUT = -1
printf("Decimal =    %d\n", EOF);               //OUTPUT = -1
printf("Octal =  %o\n", EOF);                   //OUTPUT = 37777777777
printf("Hexadecimal =  %x\n", EOF);             //OUTPUT = ffffffff
printf("Double and float =  %f\n", EOF);        //OUTPUT = 0.000000
printf("Long double =  %Lf\n", EOF);            //OUTPUT = 0.000000
printf("Character =  %c\n", EOF);               //OUTPUT = nothing

Comme nous pouvons le voir ici, EOF n'est PAS un caractère (que ce soit).

4
Carlos W. Mercado

La réponse est NON, mais ...

Vous pouvez être confus à cause du comportement de fgets()

De http://www.cplusplus.com/reference/cstdio/fgets/ :

Lit les caractères du flux et les stocke en tant que chaîne C dans str jusqu'à ce que (num-1) caractères aient été lus ou soit une nouvelle ligne soit la fin du fichier est atteint, selon la première éventualité.

1
betontalpfa

La valeur de EOF ne peut être confondue avec aucun caractère réel.

Si a= getchar(), alors nous devons déclarer a suffisamment grand pour contenir toute valeur renvoyée par getchar(). Nous ne pouvons pas utiliser char car a doit être suffisamment grand pour contenir EOF en plus des caractères.

1
Harsh Vardhan

Le caractère EOF reconnu par l'interpréteur de commandes sous Windows (et MSDOS et CP/M) est 0x1a (décimal 26, alias Ctrl + Z alias SUB))

Il peut encore être utilisé aujourd'hui, par exemple pour marquer la fin d'un en-tête lisible par l'homme dans un fichier binaire: si le fichier commence par "Some description\x1a", l'utilisateur peut vider le contenu du fichier sur la console à l'aide de la commande TYPE et le vidage s'arrêtera à EOF caractère, c'est-à-dire print Some description et s'arrêtera, au lieu de continuer avec les ordures qui suivent.

1
Axel Rietschin

Cela dépend du système mais souvent -1. Voir ici

0
onoma

Il y a la constante EOF de type int, trouvée dans stdio.h. Aucun littéral de caractère équivalent n'est spécifié par aucune norme.

0
Lundin

Je pense que cela peut varier d'un système à l'autre, mais une façon de vérifier serait d'utiliser simplement printf

#include <stdio.h>
int main(void)
{
    printf("%d", EOF);
    return 0;
}

Je l'ai fait sur Windows et -1 a été imprimé sur la console. J'espère que cela t'aides.

0
Keith Miller