Apa karakter terakhir dalam file?


19

Saya baru saja membaca jawaban untuk "Menghapus karakter baris baru di akhir file" dan semua orang berkata untuk menghapus karakter terakhir. Pertanyaan saya adalah, bukankah karakter terakhir adalah yang terakhir?



1
@SorenBjornstad Saya juga ingin menambahkan bahwa ketika ada baris baru di akhir file teks Unix, itu ada di sana karena itu mengakhiri baris terakhir. File teks kosong tidak memiliki baris baru di akhir: itu adalah urutan karakter nol.
Kaz

3
Agar sedikit bertele-tele, CPM dan DOS memang menggunakan ^ Z sebagai karakter EOF, dan Anda mungkin masih menemukan file yang diakhiri dengan ^ Z.
Edward Falk

Jawaban:


13

File tidak berakhir dengan karakter Akhir File, karena jawaban sebelumnya menyatakan dengan benar. Tapi saya pikir jawaban dan komentarnya mengandung beberapa ketidakakuratan yang layak untuk ditunjukkan:

  • Set karakter ASCII tidak mengandung karakter EOF yang tepat. Ada beberapa karakter kontrol "end": End of Text (3), End of Transmission (4), End of Transmission Block (23), End of Medium (25). Pemisah File (28) mungkin paling mendekati karakter EOF. Kode 26 adalah "Pengganti", bukan EOF.

  • Ctrl- Dhanya terkait dengan input terminal. Misalnya perintah cat filea fileb filec > outfiletidak melibatkan Ctrl- D. Omong-omong, Anda dapat mengubah karakter terminal EOF menjadi sesuatu yang lain selain Ctrl- Dmenggunakan sttyperintah.

  • Sebenarnya, Ctrl- D(atau apa pun yang telah Anda ubah) bukan kode kunci EOF. Apa yang dilakukannya adalah membuat readpanggilan sistem kembali dengan input apa yang tersedia, seperti menekan kembali membuat panggilan sistem baca mengembalikan satu baris karakter ke penelepon. Dengan konvensi, nilai balik nol dari panggilan sistem baca (yaitu karakter nol dibaca) menandakan akhir dari kondisi file. Namun, file input tidak ditutup secara otomatis, dan, jika input berasal dari terminal, itu tidak dimasukkan ke dalam status "akhir file". Anda dapat menulis program yang terus membaca dari terminal bahkan setelah "akhir file" dan panggilan baca dapat mengembalikan non-nol untuk baris input berikutnya.

  • Analogi antara karakter eof dan eol dapat dilihat jika Ctrl- Dditekan ketika beberapa input sudah ditulis di telepon. Misalnya, jika Anda menulis "abc" dan tekan Ctrl- Dpanggilan baca kembali, kali ini dengan nilai balik 3 dan dengan "abc" disimpan dalam buffer yang dilewatkan sebagai argumen. Karena baca tidak mengembalikan 0, ini tidak ditafsirkan sebagai kondisi EOF oleh konvensi di atas. Demikian pula, menekan kembali untuk membuat panggilan baca kembali dengan seluruh jalur input (termasuk baris baru). Anda dapat mencoba ini dengan catperintah: tulis beberapa karakter di telepon dan tekan Ctrl- D. Anda akan melihat karakter bergema kembali kepada Anda dan catmenunggu input lebih banyak.

  • Semua hal di atas hanya berlaku ketika terminal berada dalam mode "matang", sebagai lawan dari mode "mentah", di mana pemrosesan input jalur diminimalkan. Dalam mode mentah, karakter Ctrl-D benar-benar dikirim ke buffer input.


19

Karakter kontrol ASCII memiliki definisi dari tahun 1960-an (sebenarnya mendahului apa yang Anda anggap sebagai jaringan ). Tidak semua karakter kontrol tersebut digunakan dengan cara yang ditentukan untuk peralatan telekomunikasi saat itu.

Pada sistem mirip Unix, tidak perlu EOFkarakter; tidak ada yang digunakan. Sistem dapat memberi tahu aplikasi berapa byte dalam file:

  • Pada beberapa sistem lain (terlihat dalam VMS, DOS, Windows), kontrol-Z dapat bertindak sebagai penanda akhir file karena dalam versi yang lebih lama sistem tidak dapat memberi tahu beberapa aplikasi berapa banyak byte dalam file.

    Dalam kasus VMS, batasannya adalah karena cara runtime C bekerja. Aplikasi bahasa assembly dapat (dan memang) mendapatkan ukuran file yang benar.

  • Sistem Unix dalam shell secara konvensional menggunakan control-D untuk memberi tahu aplikasi bahwa akhir input (file) telah tercapai, tetapi control-D tidak disimpan dalam file.

Dalam C, EOFsengaja dibuat -1untuk menunjukkan bahwa itu bukan karakter yang valid. I / O standar kembali EOFketika kondisi file akhir terdeteksi - bukan karakter khusus.

Omong-omong, file tidak harus diakhiri dengan karakter baris baru (ASCII line-feed). Editor teks dapat mengatasi file yang semuanya merupakan teks yang dapat dicetak tetapi tidak memiliki baris baru.


8
POSIX mendefinisikan file teks sebagai file yang berisi urutan baris dan pada gilirannya setiap baris sebagai urutan karakter non-baris baru diikuti oleh satu baris baru. Jadi file yang diakhiri dengan apa pun kecuali 0x0A bukan file teks yang sesuai.
Damian Yerrick

2
Saya sadar akan hal itu, itulah sebabnya saya menunjukkan bahwa editor teks berfungsi. (File biner tidak memiliki kendala seperti itu).
Thomas Dickey

Sangat patut dicatat bahwa file yang dimaksudkan untuk ditangani sebagai teks yang tidak memiliki baris baru masih merupakan bentuk yang buruk (bahkan jika editor teks biasa telah dikodekan untuk mengkompensasi file tersebut), setidaknya jika Anda benar-benar ingin menjadi secara luas user-friendly / kompatibel, karena tidak adanya baris baru yang tertinggal dapat menambah kesulitan tambahan dalam berbagai keadaan (menggabungkan / mencetak beberapa file teks, parsing dengan alat baris perintah yang khas, editor minimal seperti busyboxitu vi, dll).
mtraceur

(1) Sebelum VMS, RT-11 RSX-11 TOPS-10 hanya memiliki sistem file yang tepat untuk blok dan membutuhkan karakter EOF. Begitu pula CP / M, yang tampaknya menyalinnya dari DEC dan pada gilirannya disalin oleh MS-DOS awal dan kemudian diteruskan ke Windows. (2) Di Unix, itu adalah driver tty bukan shell, seperti yang dijelaskan secara lebih rinci oleh JohanM, meskipun orang biasanya menjalankan shell pada perangkat tty.
dave_thompson_085

Tentu - DEC kembali ke sana (dan perhatikan bahwa saya menyebutkan versi yang lebih lama ). Apakah itu asal dari fitur CP / M akan menjadi topik yang menarik untuk dijelajahi (tidak di sini); Saya menyebutkan kasus-kasus itu untuk memberikan latar belakang alternatif.
Thomas Dickey

7

EOF bukan karakter. Ini adalah keadaan yang menunjukkan tidak ada lagi karakter untuk dibaca dari aliran file. Ketika Anda memasukkan perintah EOF dari terminal, Anda memberi sinyal OS untuk menutup aliran input, bukan memasukkan karakter khusus.


1
Ya tetapi dalam tabel ASCII EOF adalah 26 jadi saya pikir byte terakhir adalah representasi biner dari 26. Jadi bagaimana mungkin sebuah program yang membaca input mengetahui di mana ia berakhir?
sworwitz

ASCII dimaksudkan untuk menyampaikan informasi melalui jaringan. Dalam hal ini, Anda memerlukan karakter EOF. (ASCII memiliki banyak kode kontrol juga. Tidak semuanya dapat dicetak.) Dalam hal aliran file, ukuran file sudah diketahui melalui sistem file sehingga OS dapat mengetahui kapan tidak ada lagi data untuk dibaca.
Munir

@sworwitz: Sehubungan dengan C, fungsi pembacaan input yang mengembalikan karakter per panggilan mengembalikan int (biasanya nomor 32 bit tetapi harus minimum 16 bit) bukan char. Fungsi memberi sinyal dan EOF dengan mengembalikan -1 (0xffffffff) yang bukan nilai 8 bit yang valid sehingga tidak akan dikacaukan oleh karakter ASCII, bahkan 0xff. Fungsi yang mengembalikan string juga mengembalikan panjang data yang dibaca. Panjang ini dapat digunakan untuk memberi sinyal tidak ada data atau data akhir (sekali lagi, panjangnya bisa -1). Akhirnya, ada juga fungsi yang dapat Anda panggil yang akan memberi tahu Anda jika aliran telah mencapai akhir
slebetman

Oke terima kasih! Jadi ketika di bash saya tekan Ctrl + d saya memberikan input karakter ASCII, kan?
sworwitz

@sworwitz Tidak juga. Sebelum bashmendapatkan input, dipijat oleh driver TTY. Pengandar ini memotong Ctrl-D dan mengirim EOF ke bash (Di mana EOF bukan karakter, tetapi status file khusus)
Stig Hemmer
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.