TL; DR : EOF bukan karakter, ini adalah makro yang digunakan untuk mengevaluasi pengembalian negatif dari fungsi membaca-input. Orang dapat menggunakan Ctrl+ Duntuk mengirim EOT
karakter yang akan memaksa fungsi kembali-1
Setiap programmer harus RTFM
Mari kita merujuk ke "Manual Referensi CA", oleh Harbison dan Steele, edisi ke-4. dari 1995, halaman 317:
EOF bilangan bulat negatif adalah nilai yang bukan merupakan pengkodean "karakter nyata". . . Misalnya fget (bagian 15.6) mengembalikan EOF ketika pada akhir file, karena tidak ada "karakter nyata" untuk dibaca.
Pada dasarnya EOF
bukan karakter, melainkan nilai integer yang diterapkan stdio.h
untuk mewakili -1
. Jadi, jawaban kos itu benar sejauh yang dikatakan, tetapi ini bukan tentang menerima input "kosong". Catatan penting adalah bahwa di sini EOF berfungsi sebagai nilai pengembalian (dari getchar()
) perbandingan, bukan untuk menandakan karakter yang sebenarnya. The man getchar
mendukung bahwa:
NILAI KEMBALI
fgetc (), getc () dan getchar () mengembalikan karakter yang dibaca sebagai karakter yang tidak ditandatangani ke int atau EOF di akhir file atau kesalahan.
mendapat () dan fgets () mengembalikan s pada keberhasilan, dan NULL pada kesalahan atau ketika akhir file terjadi saat tidak ada karakter yang telah dibaca.
ungetc () mengembalikan c saat berhasil, atau EOF jika salah.
Pertimbangkan while
loop - tujuan utamanya adalah mengulangi tindakan jika kondisi dalam tanda kurung benar . Lihat lagi:
while ((c = getchar ()) != EOF)
Itu pada dasarnya mengatakan tetap melakukan hal-hal jika c = getchar()
mengembalikan kode yang berhasil ( 0
atau di atas; itu adalah hal yang umum, coba jalankan perintah yang berhasil, echo $?
kemudian gagal echo $?
dan lihat angka mereka kembali). Jadi jika kita berhasil mendapatkan karakter dan assing ke C, kode status yang dikembalikan adalah 0, gagal adalah -1. EOF
didefinisikan sebagai -1
. Karena itu ketika kondisi -1 == -1
terjadi, loop berhenti. Dan kapan itu akan terjadi? Ketika tidak ada lagi karakter yang didapat, saat c = getchar()
gagal. Anda bisa menulis while ((c = getchar ()) != -1)
dan itu masih akan berhasil
Juga, mari kita kembali ke kode aktual, ini kutipan dari stdio.h
/* End of file character.
Some things throughout the library rely on this being -1. */
#ifndef EOF
# define EOF (-1)
#endif
Kode dan EOT ASCII
Meskipun karakter EOF bukan karakter aktual, namun, ada karakter EOT
(End of Transmission), yang memiliki nilai desimal ASCII dari 04; itu ditautkan ke Ctrl+ Dpintasan (diwakili juga sebagai karakter meta ^D
). Akhir dari karakter transmisi digunakan untuk menandakan penutupan aliran data kembali ketika komputer digunakan untuk mengontrol koneksi telepon, karenanya penamaan "end of transmission".
Jadi dimungkinkan untuk mengirim nilai ascii ke program seperti itu, perhatikan $'\04'
EOT yang mana:
skolodya@ubuntu:$ ./a.out <<< "a,b,c $'\04'"
digits = 1 0 0 0 1 0 0 0 0 0, white space = 2, other = 9
Dengan demikian, kita dapat mengatakan bahwa itu memang ada, tetapi tidak dapat dicetak
Catatan Samping
Kita sering lupa bahwa di masa lalu komputer tidak serba guna - desainer harus menggunakan setiap tombol keyboard yang tersedia. Dengan demikian, mengirim EOT
karakter dengan CtrlD masih "mengirim karakter", tidak seperti mengetik huruf A, ShiftA, Anda masih membuat memberi komputer input dengan kunci yang tersedia. Jadi EOT adalah karakter nyata dalam arti bahwa itu memang berasal dari pengguna, dapat dibaca oleh komputer (meskipun tidak dapat dicetak, tidak terlihat oleh manusia), itu ada dalam memori komputer
Komentar Byte Commander
Jika Anda mencoba membaca dari / dev / null, itu seharusnya mengembalikan EOF juga, kan? Atau apa yang saya dapatkan di sana?
Ya, tepat sekali, karena di /dev/null
sana tidak ada karakter aktual untuk dibaca, maka itu c = getchar()
akan mengembalikan -1
kode, dan program akan segera berhenti. Sekali lagi perintah tidak mengembalikan EOF. EOF hanyalah variabel konstan sama dengan -1, yang kami gunakan untuk membandingkan kode pengembalian fungsi getchar . EOF
tidak ada sebagai karakter, itu hanya nilai statis di dalamnya 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
Paku lain di peti mati
Terkadang dicoba untuk dibuktikan bahwa EOF adalah karakter dengan kode seperti ini:
#include <stdio.h>
int main(void)
{
printf("%c", EOF);
return 0;
}
Masalah dengan itu adalah bahwa datatype char bisa menjadi nilai yang ditandatangani atau tidak. Selain itu mereka adalah datatype terkecil yang membuatnya sangat berguna dalam mikrokontroler, di mana memori terbatas. Jadi, alih-alih mendeklarasikannya int foo = 25;
, biasanya terlihat di mikrokontroler dengan memori kecil char foo = 25;
atau yang serupa. Selain itu, karakter dapat ditandatangani atau tidak ditandatangani .
Orang dapat memverifikasi bahwa ukuran dalam byte dengan program seperti ini:
#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
Apa sebenarnya intinya? Intinya adalah bahwa EOF didefinisikan sebagai -1, tetapi char datatype dapat mencetak nilai integer .
BAIK . . jadi bagaimana jika kita mencoba mencetak char sebagai string?
#include <stdio.h>
int main(void)
{
printf("%s", EOF);
return 0;
}
Jelas kesalahan, tapi tetap saja, kesalahan akan memberi tahu kita sesuatu yang menarik:
skolodya @ ubuntu: $ gcc EOF.c -o EOF
EOF.c: Dalam fungsi 'main': EOF.c: 4: 5: peringatan: format '% s' mengharapkan argumen tipe 'char *', tetapi argumen 2 memiliki ketik 'int'
[-Wformat =] printf ("% s", EOF);
Nilai hex
Mencetak EOF sebagai nilai hex memberi FFFFFFFF
, nilai 16 bit (8 byte), pujian dua dari a -1
.
#include <stdio.h>
int main(void)
{
printf("This is EOF: %X\n", EOF);
printf("This is Z: %X\n",'Z');
return 0;
}
Keluaran:
DIR:/xieerqi
skolodya@ubuntu:$ ./EOF
This is EOF: FFFFFFFF
This is Z: 5A
Hal aneh lain terjadi dengan kode berikut:
#include <stdio.h>
int main(void)
{
char c;
if (c = getchar())
printf ("%x",c);
return 0;
}
Jika satu menekan Shift+ A, kita mendapatkan nilai hex 41, jelas sama seperti pada tabel ASCII. Tetapi untuk Ctrl+ D, kami memiliki ffffffff
, sekali lagi - nilai balik dari yang getchar()
disimpan di 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
Rujuk ke bahasa lain
Perhatikan bahwa bahasa lain menghindari kebingungan ini, karena mereka beroperasi pada evaluasi status keluar fungsi, tidak membandingkannya dengan makro. Bagaimana cara membaca file di Java?
File inputFile = new File (filename);
Scanner readFile = new Scanner(inputFile);
while (readFile.hasNext())
{ //more code bellow }
Bagaimana dengan python?
with open("/etc/passwd") as file:
for line in file:
print line
-1
setara dengan EOF. Ini didefinisikan/usr/include/stdio.h
sebagai konstanta makro