Reprezentowanie EOF w kodzie C?

Znak nowej linii jest reprezentowany przez "\n" w kodzie C. Czy istnieje odpowiednik dla znaku końca pliku (EOF)?

Author: static_rtti, 2012-09-12

10 answers

EOF nie jest znakiem (w większości nowoczesnych systemów operacyjnych). Jest to po prostu warunek, który odnosi się do strumienia plików po osiągnięciu końca strumienia. Zamieszanie powstaje, ponieważ użytkownik może sygnalizować EOF dla wejścia konsoli wpisując znak specjalny (np. Control-D w Unix, Linux, Et al), ale ten znak nie jest widziany przez uruchomiony program, jest przechwytywany przez system operacyjny, który w kolei sygnalizuje procesowi EOF.

Uwaga: w niektórych bardzo starych działających system EOF był znakiem, np. Control-Z w CP / M, ale był to prymitywny hack, aby uniknąć kosztów utrzymania rzeczywistej długości plików w katalogach systemu plików.

 51
Author: Paul R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-10 22:36:18

Nie. EOF nie jest znakiem, ale stanem pliku.

Chociaż w zestawie znaków ASCII znajdują się znaki kontrolne, które reprezentują koniec danych, nie są one używane do sygnalizowania końca plików w ogóle. Na przykład EOT (^D), które w niektórych przypadkach prawie sygnalizują to samo.

Gdy standardowa biblioteka C używa signed integer do zwracania znaków i używa -1 do końca pliku, jest to w rzeczywistości tylko sygnał wskazujący, że wystąpił błąd. I nie ma dostępnego standardu C, ale cytując SUSv3:

Jeśli ustawiony jest wskaźnik końca pliku dla strumienia lub jeśli strumień znajduje się na końcu pliku, ustawiany jest wskaźnik końca pliku dla strumienia, a fgetc() zwraca EOF. Jeśli wystąpi błąd odczytu, ustawia się wskaźnik błędu dla strumienia, fgetc () zwraca EOF i ustawia errno, aby wskazać błąd.

 7
Author: pmakholm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 13:58:01

EOF nie jest postacią. Nie może być: plik (binarny) może zawierać dowolny znak. Załóżmy, że masz plik z ciągle rosnącymi bajtami, idąc 0 1 2 3 ... 255 i jeszcze raz 0 1 ... 255, w sumie 512 bajtów. Niezależnie od tego, który z tych 256 możliwych bajtów uznasz za EOF, plik zostanie skrócony.

Dlatego getchar() et al. return an int. Zakres możliwych wartości zwrotnych to te, które może mieć char, plus prawdziwa int wartość EOF (zdefiniowana w stdio.h). Dlatego też Konwersja wartości zwracanej na char przed sprawdzanie EOF nie zadziała.

Zauważ, że niektóre protokoły mają znaki "EOF"."ASCII ma "koniec tekstu", "koniec transmisji"," koniec bloku transmisji " i "koniec Medium". Inne odpowiedzi mówiły o starych OS ' ach. Ja sam wprowadzam ^D na Linuksie i ^z na konsolach Windows, aby przestać dawać programy wejściowe. (Ale pliki odczytywane przez rury mogą mieć znaki ^D i ^z w dowolnym miejscu i sygnalizować EOF tylko wtedy, gdy zabraknie bajtów.) C łańcuchy są zakończone znakiem '\0', ale oznacza to również, że nie mogą zawierać znaku '\0'. Dlatego wszystkie C nie-ciągowe funkcje danych działają przy użyciu tablicy char (aby zawierać dane) i size_t (aby wiedzieć, gdzie DANE się kończą).

Edit: standard C99 §7.19.1.3 stwierdza:

Makra to [...]
EOF
który rozszerza się do wyrażenia stałej całkowitej, o typie int i wartości ujemnej, która jest zwracana przez kilka funkcje do oznacza to, że nie ma więcej danych wejściowych ze strumienia;

 5
Author: aib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 15:25:34

Przeczytałem wszystkie komentarze. Ciekawie jest zauważyć, co się dzieje, gdy to drukujesz:

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

Jak widać tutaj, EOF nie jest postacią (w ogóle).

 2
Author: Carlos W. Mercado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 15:28:53

Znak EOF rozpoznawany przez interpreter poleceń w Windows (i MSDOS oraz CP/M) to 0x1a (decimal 26, aka Ctrl+Z aka SUB)

Może być nadal używany na przykład do oznaczania końca czytelnego dla człowieka nagłówka w pliku binarnym: jeśli plik zaczyna się od "Some description\x1a", użytkownik może zrzucić zawartość pliku do konsoli za pomocą polecenia TYPE, a zrzut zatrzyma się na znaku EOF , tzn. wydrukować jakiś opis i zatrzymać, zamiast kontynuować ze śmieciami, które następują.

 1
Author: Axel Rietschin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-01 20:00:57

Wartość EOF nie może być mylona z żadnym prawdziwym znakiem.

If a= getchar(), then we must declare a big enough to hold any value that getchar() returns. Nie możemy użyć char, ponieważ a musi być wystarczająco duży, aby trzymać EOF oprócz znaków.

 1
Author: Harsh Vardhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-27 14:01:55

Odpowiedź brzmi nie, ale...

Możesz pomylić z powodu zachowania fgets()

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

Odczytuje znaki ze stream i zapisuje je jako ciąg C do str, dopóki znaki (num-1) nie zostaną odczytane lub zostanie osiągnięty znak nowej linii lub końca pliku, w zależności od tego, co nastąpi wcześniej.

 1
Author: betontalpfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-23 10:50:44

Jest to zależne od systemu, ale często -1. Zobacz tutaj

 0
Author: onoma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 13:42:40

Istnieje stała EOF typu int, znaleziona w stdio.h. nie ma równoważnego literału znakowego określonego przez jakikolwiek standard.

 0
Author: Lundin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 13:42:51

Myślę, że może się różnić w zależności od systemu, ale jednym ze sposobów sprawdzenia byłoby użycie printf

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

Zrobiłem to na Windows i -1 został wydrukowany na konsoli. Mam nadzieję, że to pomoże.

 0
Author: Keith Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 13:43:40