To jest mój kod źródłowy C.
Kiedy buduję go w Ubuntu, zaczyna on zbierać znaki, ale nie wiem, jak zakończyć program, ponieważ nie kończy się on na wprowadzeniu ENTERlub znaku powrotu karetki.
Co oznacza EOF? Jak mogę go uruchomić?
To źródło znajduje się również w książce Dennisa Ritchie:
#include <stdio.h>
/* count digits, white space, others */
main ()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar ()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf ("digits =");
for (i = 0; i < 10; ++i)
printf (" %d", ndigit[i]);
printf (", white space = %d, other = %d\n", nwhite, nother);
}
command-line
c
programator stosów
źródło
źródło
-1
jest równoważne EOF. Jest zdefiniowany/usr/include/stdio.h
jako stała makro-1
jako dane wejściowe nie działa :)Odpowiedzi:
Tl; dr
Generalnie można „wyzwolić EOF” w programie działającym w terminalu za pomocą klawisza CTRL+ Dtuż po ostatnim płukaniu wejścia.
EOF oznacza koniec pliku.
„Wyzwalanie EOF” w tym przypadku z grubsza oznacza „uświadomienie programowi, że nie będzie wysyłane więcej danych wejściowych”.
W takim przypadku, ponieważ
getchar()
zwróci liczbę ujemną, jeśli żaden znak nie zostanie odczytany, wykonanie zostanie zakończone.Ale dotyczy to nie tylko konkretnego programu, ale także wielu różnych narzędzi.
Zasadniczo „wyzwalanie EOF” można wykonać za pomocą klawisza CTRL+ Dzaraz po ostatnim płukaniu wejścia (tj. Wysyłając puste wejście).
Na przykład z
cat
:To, co dzieje się pod maską po naciśnięciu CTRL+, Dpolega na tym, że dane wejściowe wpisane od ostatniego koloru wejściowego są opróżniane; kiedy to okazuje się być pusta wprowadzić
read()
syscall wezwał programu stdin zwrotów0
,getchar()
zwraca liczbę ujemną (-1
w bibliotece GNU C), a to z kolei jest interpretowane jako EOF 1 .1 - /programming//a/1516177/4316166
źródło
TL; DR : EOF nie jest znakiem, to makro używane do oceny ujemnego zwrotu funkcji odczytu danych wejściowych. Można użyć Ctrl+, Daby wysłać
EOT
znak, który wymusi powrót funkcji-1
Każdy programista musi RTFM
Odwołajmy się do „CA Reference Manual” Harbison i Steele, wydanie 4. od 1995 r., strona 317:
Zasadniczo
EOF
nie jest postacią, ale raczej liczbą całkowitą zaimplementowanąstdio.h
do reprezentowania-1
. Tak więc odpowiedź kos jest poprawna, ale nie chodzi o otrzymywanie „pustych” danych wejściowych. Ważna uwaga jest taka, że tutaj EOF służy jako wartości zwracanej (zgetchar()
) stosunku, aby nie oznaczać rzeczywistego charakteru. Naman getchar
podpory, że:Rozważmy
while
pętlę - jej podstawowym celem jest powtórzenie akcji, jeśli warunek w nawiasach jest spełniony . Spójrz ponownie:Zasadniczo mówi: kontynuuj robienie rzeczy, jeśli
c = getchar()
zwróci udany kod (0
lub wyższy; przy okazji, spróbuj wykonać udane polecenie,echo $?
a potem się nie powiedzieecho $?
i zobacz liczby, które zwracają). Więc jeśli uda nam się uzyskać znak i przydzielić C, zwrócony kod stanu to 0, błąd to -1.EOF
jest zdefiniowany jako-1
. Dlatego gdy-1 == -1
wystąpi warunek , pętle zatrzymują się. A kiedy to się stanie? Gdy nie ma już postaci do zdobycia, gdy sięc = getchar()
nie powiedzie. Możesz pisaćwhile ((c = getchar ()) != -1)
i nadal będzie działaćWróćmy też do samego kodu, oto fragment
stdio.h
Kody ASCII i EOT
Chociaż znak EOF nie jest znakiem rzeczywistym, istnieje
EOT
znak (End of Transmission), który ma wartość dziesiętną ASCII 04; jest połączony ze skrótem Ctrl+ D(reprezentowanym również jako znak meta^D
). Znak końca transmisji używany do oznaczania zamknięcia strumienia danych z powrotem, gdy komputery były używane do kontrolowania połączeń telefonicznych, stąd nazewnictwo „koniec transmisji”.Możliwe jest przesłanie takiej wartości ascii do programu w ten sposób, zwróć uwagę na
$'\04'
to, co jest EOT:Możemy zatem powiedzieć, że istnieje, ale nie można go wydrukować
Dygresja
Często zapominamy, że w przeszłości komputery nie były tak wszechstronne - projektanci musieli korzystać z każdego dostępnego klawisza klawiatury. Tak więc, wysyłanie
EOT
znaku za pomocą CtrlD nadal „wysyła znak”, podobnie jak pisanie wielką literą A, ShiftA, nadal dajesz komputerowi wejście z dostępnymi kluczami. Zatem EOT jest prawdziwą postacią w tym sensie, że pochodzi od użytkownika, jest czytelny dla komputera (choć nie do wydrukowania, niewidoczny dla ludzi), istnieje w pamięci komputeraKomentarz Byte Commander
Tak, dokładnie tak, ponieważ
/dev/null
nie ma żadnego rzeczywistego znaku do odczytania, dlategoc = getchar()
zwróci-1
kod, a program natychmiast zakończy działanie. Ponownie polecenie nie zwraca EOF. EOF to tylko stała zmienna równa -1, której używamy do porównywania kodu powrotu funkcji getchar .EOF
nie istnieje jako postać, jest tylko wartością statyczną w środkustdio.h
.Próbny:
Kolejny gwóźdź do trumny
Czasami próbuje się udowodnić, że EOF jest znakiem o takim kodzie:
Problem w tym, że typ danych char może być wartością podpisaną lub niepodpisaną. Ponadto są najmniejszymi adresowalnymi typami danych, co czyni je bardzo przydatnymi w mikrokontrolerach, w których pamięć jest ograniczona. Zamiast deklarować
int foo = 25;
, często obserwuje się w mikrokontrolerach z małą pamięciąchar foo = 25;
lub czymś podobnym. Ponadto znaki mogą być podpisane lub niepodpisane .Można sprawdzić, czy rozmiar w bajtach za pomocą takiego programu:
O co dokładnie chodzi? Chodzi o to, że EOF jest zdefiniowany jako -1, ale typ danych char może wydrukować wartości całkowite .
OK . . . więc co, jeśli spróbujemy wydrukować znak jako ciąg?
Oczywiście błąd, ale błąd powie nam coś ciekawego:
Wartości szesnastkowe
Drukowanie EOF jako wartości szesnastkowej daje
FFFFFFFF
16-bitową (8-bajtową) wartość, komplement dwóch z a-1
.Wynik:
Następująca ciekawa rzecz występuje z następującym kodem:
Jeśli naciśniesz Shift+ A, otrzymamy wartość szesnastkową 41, oczywiście taką samą jak w tabeli ASCII. Ale dla Ctrl+ Dmamy
ffffffff
ponownie wartość zwracanągetchar()
przechowywaną wc
.Zobacz inne języki
Zauważ, że inne języki unikają tego zamieszania, ponieważ działają na ocenie stanu wyjścia funkcji, a nie na porównaniu z makrem. Jak można odczytać plik w Javie?
Co powiesz na python?
źródło
/dev/null
, to również powinien zwrócić EOF, prawda? A co tam dostanę?EOF oznacza koniec pliku . Chociaż nie wiem, jak wywołać następujący symbol, możesz uruchomić następujący program poprzez potokowanie pliku, który wysyła sygnał EOF na końcu:
gdzie
a.out
jest twoje skompilowane źródłoźródło
read()
(syscall) powróci0
, co jest interpretowane jako EOF: stackoverflow.com/a/1516177/4316166