TL; DR : EOF ist kein Zeichen, sondern ein Makro zur Bewertung der negativen Rückgabe einer Eingabe-Lesefunktion. Man kann Ctrl+ verwenden D, um EOTZeichen zu senden , die die Funktionsrückgabe erzwingen-1
Jeder Programmierer muss RTFM
Wir verweisen auf "CA Reference Manual" von Harbison und Steele, 4. Aufl. ab 1995, Seite 317:
Die negative Ganzzahl EOF ist ein Wert, der keine Codierung eines "echten Zeichens" ist. . . Zum Beispiel gibt fget (Abschnitt 15.6) am Ende der Datei EOF zurück , da kein "echtes Zeichen" zu lesen ist.
Im Wesentlichen EOFhandelt es sich nicht um ein Zeichen, sondern um einen ganzzahligen Wert , der stdio.hzur Darstellung implementiert ist -1. Somit ist die Antwort von kos soweit richtig, aber es geht nicht darum, "leere" Eingaben zu erhalten. Wichtiger Hinweis ist, dass hier EOF als Rückgabewert (des getchar()) Vergleichs dient, nicht um ein tatsächliches Zeichen zu kennzeichnen. Das man getcharunterstützt das:
RÜCKGABEWERT
fgetc (), getc () und getchar () geben das als vorzeichenloses Zeichen gelesene Zeichen am Ende der Datei oder des Fehlers an einen int oder EOF zurück.
get () und fgets () geben s bei Erfolg zurück und NULL bei Fehler oder wenn das Dateiende eintritt, während keine Zeichen gelesen wurden.
ungetc () gibt bei Erfolg c oder bei Fehler EOF zurück.
Betrachten Sie die whileSchleife - ihr Hauptzweck besteht darin, die Aktion zu wiederholen, wenn die Bedingung in den Klammern erfüllt ist . Schau nochmal:
while ((c = getchar ()) != EOF)
Grundsätzlich heißt es, mach weiter, wenn c = getchar()erfolgreicher Code zurückgegeben wird ( 0oder höher; es ist übrigens üblich, einen erfolgreichen Befehl auszuführen , dann echo $?und dann fehlgeschlagen echo $?und die zurückgegebenen Zahlen zu sehen). Wenn wir also erfolgreich Zeichen erhalten und C zuordnen, ist der zurückgegebene Statuscode 0, fehlgeschlagen -1. EOFist definiert als -1. Wenn ein Zustand -1 == -1eintritt, werden die Schleifen daher gestoppt. Und wann wird das passieren? Wenn kein Charakter mehr zu bekommen ist, wenn er c = getchar()fehlschlägt. Sie könnten schreiben while ((c = getchar ()) != -1)und es würde immer noch funktionieren
Kehren wir auch zum eigentlichen Code zurück. Hier ist ein Auszug aus stdio.h
/* End of file character.
Some things throughout the library rely on this being -1. */
#ifndef EOF
# define EOF (-1)
#endif
ASCII-Codes und EOT
Obwohl das EOF-Zeichen kein tatsächliches Zeichen ist, gibt es ein EOT(Ende der Übertragung) Zeichen mit dem ASCII-Dezimalwert 04; Es ist mit der Verknüpfung Ctrl+ verknüpft D(auch als Metazeichen dargestellt ^D). Das Ende der Übertragung wird verwendet, um das Schließen eines Datenstroms vor langer Zeit anzuzeigen, als Computer zur Steuerung von Telefonverbindungen verwendet wurden, daher die Benennung "Ende der Übertragung".
Es ist also möglich, diesen ASCII-Wert wie $'\04'folgt an das Programm zu senden. Beachten Sie Folgendes: EOT:
skolodya@ubuntu:$ ./a.out <<< "a,b,c $'\04'"
digits = 1 0 0 0 1 0 0 0 0 0, white space = 2, other = 9
Wir können also sagen, dass es existiert, aber es ist nicht druckbar
Randnotiz
Wir vergessen oft, dass Computer in der Vergangenheit nicht so vielseitig waren - Designer müssen jede verfügbare Tastaturtaste verwenden. Das Senden eines EOTZeichens mit StrgD bedeutet also immer noch "Senden eines Zeichens", ähnlich wie bei der Eingabe von Großbuchstaben A und ShiftA. Sie geben dem Computer dennoch eine Eingabe mit verfügbaren Schlüsseln. Somit ist EOT ein realer Charakter in dem Sinne, dass es vom Benutzer stammt, vom Computer lesbar ist (obwohl es nicht druckbar ist, für Menschen nicht sichtbar), es existiert im Computerspeicher
Kommentar von Byte Commander
Wenn Sie versuchen, aus / dev / null zu lesen, sollte dies auch einen EOF zurückgeben, oder? Oder was bekomme ich dort?
Ja, genau richtig, da /dev/nulldarin kein tatsächlich zu lesendes Zeichen vorhanden ist. Daher c = getchar()wird -1Code zurückgegeben und das Programm wird sofort beendet. Wieder gibt der Befehl EOF nicht zurück. EOF ist nur eine konstante Variable gleich -1, mit der wir den Rückkehrcode der Funktion getchar vergleichen . EOFexistiert nicht als Zeichen, es ist nur ein statischer Wert im Inneren stdio.h.
Demo:
# cat /dev/null shows there's no readable chars
DIR:/xieerqi
skolodya@ubuntu:$ cat /dev/null | cat -A
# Bellow is simple program that will open /dev/null for reading. Note the use of literal -1
DIR:/xieerqi
skolodya@ubuntu:$ cat readNull.c
#include<stdio.h>
void main()
{
char c;
FILE *file;
file = fopen("/dev/null", "r");
if (file)
{
printf ("Before while loop\n");
while ((c = getc(file)) != -1)
putchar(c);
printf("After while loop\n");
fclose(file);
}
}
DIR:/xieerqi
skolodya@ubuntu:$ gcc readNull.c -o readNull
DIR:/xieerqi
skolodya@ubuntu:$ ./readNull
Before while loop
After while loop
Ein weiterer Nagel im Sarg
Manchmal wird versucht zu beweisen, dass EOF ein Zeichen mit einem Code wie diesem ist:
#include <stdio.h>
int main(void)
{
printf("%c", EOF);
return 0;
}
Das Problem dabei ist, dass der Datentyp char ein vorzeichenbehafteter oder vorzeichenloser Wert sein kann. Darüber hinaus sind sie der kleinste adressierbare Datentyp, was sie in Mikrocontrollern mit begrenztem Speicher sehr nützlich macht. Anstatt zu deklarieren int foo = 25;, ist es üblich, in Mikrocontrollern mit kleinem Speicher char foo = 25;oder ähnlichem zu sehen. Außerdem können Zeichen signiert oder nicht signiert sein .
Mit einem Programm wie diesem könnte man die Größe in Bytes überprüfen:
#include <stdio.h>
int main(void)
{
printf("Size of int: %lu\n",sizeof(int));
printf("Sieze of char: %lu\n",sizeof(char));
//printf("%s", EOF);
return 0;
}
skolodya@ubuntu:$ ./EOF
Size of int: 4
Sieze of char: 1
Was genau ist der Punkt? Der Punkt ist, dass EOF als -1 definiert ist, der Datentyp char jedoch ganzzahlige Werte drucken kann .
IN ORDNUNG . . Was ist, wenn wir versuchen, char als Zeichenfolge zu drucken?
#include <stdio.h>
int main(void)
{
printf("%s", EOF);
return 0;
}
Offensichtlich ein Fehler, aber dennoch wird uns ein Fehler etwas Interessantes sagen:
skolodya @ ubuntu: $ gcc EOF.c -o EOF
EOF.c: In Funktion 'main': EOF.c: 4: 5: Warnung: Format '% s' erwartet Argument vom Typ 'char *', aber Argument 2 hat Typ 'int'
[-Wformat =] printf ("% s", EOF);
Hex-Werte
Das Drucken von EOF als Hex-Wert ergibt FFFFFFFFeinen 16-Bit-Wert (8 Byte), zwei Komplimente von a -1.
#include <stdio.h>
int main(void)
{
printf("This is EOF: %X\n", EOF);
printf("This is Z: %X\n",'Z');
return 0;
}
Ausgabe:
DIR:/xieerqi
skolodya@ubuntu:$ ./EOF
This is EOF: FFFFFFFF
This is Z: 5A
Eine andere merkwürdige Sache tritt mit dem folgenden Code auf:
#include <stdio.h>
int main(void)
{
char c;
if (c = getchar())
printf ("%x",c);
return 0;
}
Wenn man Shift+ drückt A, erhält man den Hex-Wert 41, offensichtlich wie in der ASCII-Tabelle. Aber für Ctrl+ Dhaben wir ffffffffwieder - den Rückgabewert von getchar()gespeichert in c.
DIR:/xieerqi
skolodya@ubuntu:$ gcc EOF.c -o ASDF.asdf
DIR:/xieerqi
skolodya@ubuntu:$ ./ASDF.asdf
A
41
DIR:/xieerqi
skolodya@ubuntu:$ ./ASDF.asdf
ffffffff
Beziehen Sie sich auf andere Sprachen
Beachten Sie, dass andere Sprachen diese Verwirrung vermeiden, da sie einen Funktions-Exit-Status auswerten und nicht mit einem Makro vergleichen. Wie liest man eine Datei in Java?
File inputFile = new File (filename);
Scanner readFile = new Scanner(inputFile);
while (readFile.hasNext())
{ //more code bellow }
Wie wäre es mit Python?
with open("/etc/passwd") as file:
for line in file:
print line
-1entspricht EOF. Es ist/usr/include/stdio.hals Makrokonstante definiert