Bir dosyadaki son karakter nedir?


19

Sadece "Dosyanın sonundaki yeni satır karakterini kaldırma" yanıtlarını okudum ve herkes son karakteri silmeyi söyledi. Sorum şu: son karakter değil mi?



1
@SorenBjornstad Ayrıca, bir Unix metin dosyasının sonunda bir yeni satır olduğunda, son satırı sonlandırdığı için orada olduğunu da eklemek isterim. Boş bir metin dosyasının sonunda yeni satır yoktur: sıfır karakter dizisidir.
Kaz

3
Biraz bilgiçlik göstermek için CPM ve DOS, EOF karakteri olarak ^ Z kullandılar ve bazen ^ Z ile biten dosyalarla karşılaşabilirsiniz.
Edward Falk

Yanıtlar:


13

Önceki yanıtlar doğru şekilde belirtildiği için bir dosya Dosya Sonu karakteriyle bitmiyor. Ama cevapların ve yorumların belirtmeye değer bazı yanlışlıklar içerdiğini düşünüyorum:

  • ASCII karakter kümesi tam bir EOF karakteri içermiyor. Birkaç "son" kontrol karakteri vardır: Metin Sonu (3), İletim Sonu (4), İletim Sonu Bloğu (23), Orta Sonu (25). Dosya Ayırıcı (28) belki bir EOF karakterine en yakın gelir. Kod 26, EOF değil, "Yedek" tir.

  • Ctrl- Dsadece terminal girişi ile ilişkilidir. Örneğin komut cat filea fileb filec > outfileiçermez Ctrl- D. Bu arada, daha başka bir şeye terminali EOF karakterini değiştirebilir Ctrl- Dkullanarak sttykomut.

  • Açıkçası, Ctrl- D(veya değiştirdiğiniz her şey) bir EOF anahtar kodu değildir. Yaptığı şey, readsistem çağrısının kullanılabilir olan girişle geri dönmesini sağlamaktır, tıpkı dönüş tuşuna basmak gibi, okuma sistemi çağrısını arayan kişiye bir karakter satırı döndürür. Geleneksel olarak , okuma sistemi çağrısı (yani sıfır karakter okuma) sıfıra kadar bir geri dönüş değeri dosya bir durumun sonuna işaret eder. Ancak, giriş dosyası otomatik olarak kapatılmaz ve giriş uçbirimden geliyorsa, "dosya sonu" durumuna getirilmez. "Dosya sonu" ndan sonra bile terminalden okumaya devam eden bir program yazabilirsiniz ve okuma çağrısı bir sonraki giriş satırı için sıfırdan farklı olabilir.

  • Satırda zaten bir girdi yazıldığında Ctrl- Dtuşuna basılırsa eof ve eol karakterleri arasındaki benzerlik görülebilir . Örneğin, "abc" yazarsanız ve tuşuna basarsanız Ctrl- Dokuma çağrısı geri döner, bu kez 3 dönüş değeri ve tamponda saklanan "abc" ile argüman olarak iletilir. Okuma 0 döndürmediği için, yukarıdaki kural uyarınca EOF koşulu olarak yorumlanmaz. Benzer şekilde, geri dönmek için tuşuna basıldığında, okunan çağrı tüm giriş satırıyla (satırsonu dahil) geri döner. Sen ile bu deneyebilir catkomutu: hat ve basın üzerindeki bazı karakterler yazma Ctrl- D. Karakterlerin size geri döndüğünü ve catdaha fazla girdi beklediğini göreceksiniz .

  • Yukarıdakilerin tümü, hat girişi işleminin en aza indirildiği "ham" modun aksine, terminal "pişmiş" moddayken geçerlidir. Ham modda, giriş arabelleğine gerçekten bir Ctrl-D karakteri verilir.


19

ASCII kontrol karakterleri 1960'lardan tanımlara sahiptir (aslında bir ağ olarak düşünebileceğiniz şeyden önce ). Bu kontrol karakterlerinin tümü, o zamanlar telekomünikasyon ekipmanı için tanımlandıkları şekilde kullanılmaz.

Unix benzeri sistemlerde, bir EOFkaraktere gerek yoktur ; hiçbiri kullanılmaz. Sistem uygulamalara bir dosyada kaç bayt olduğunu söyleyebilir:

  • Diğer bazı sistemlerde (VMS, DOS, Windows'da görülür), bir kontrol Z dosya sonu işareti olarak işlev görebilir, çünkü eski sürümlerde sistem bazı uygulamalarda dosyada kaç bayt olduğunu söyleyememiştir.

    VMS durumunda, sınırlama C çalışma zamanının çalışma şeklinden kaynaklanıyordu. Montaj dili uygulamaları doğru dosya boyutunu alabilir (ve edinebilir).

  • Unix sistemleri kabuk geleneksel girişi (dosyası) bir uç ulaşıldı, fakat kontrol-D dosyasında kayıtlı ilişkin bir uygulama anlatmak için kontrol D kullanın.

C'de, EOFbilerek -1geçerli bir karakter olmadığını belirtmek için yapılır . EOFBir dosya sonu koşulu algılandığında standart G / Ç geri döner - özel bir karakter değil.

Bu arada, dosyaların yeni satır (ASCII satır besleme) karakteriyle bitmesi gerekmez . Metin editörleri, tümü yazdırılabilir metin olan ancak sondaki satır sonu olmayan dosyalarla başa çıkabilir.


8
POSIX, bir metin dosyasını bir satır sırası içeren bir dosya olarak tanımlar ve sırayla her satırı bir satırsonu karakteri olmayan ve bir satırsonu karakteri olarak tanımlar . Bu nedenle 0x0A dışında bir şeyle biten bir dosya, uyumlu bir metin dosyası değildir.
Damian Yerrick

2
Bunun farkındayım, bu yüzden metin editörlerinin çalıştığına dikkat çektim . (İkili dosyaların böyle bir kısıtlaması yoktur).
Thomas Dickey

Sonunda yeni satır içermeyen metin olarak kullanılması amaçlanan dosyaların hala tartışmasız kötü bir form olduğunu (tipik metin editörleri bu tür dosyaları telafi etmek için kodlanmış olsa bile), en azından gerçekten olmasını istiyorsanız, geniş bir kullanıcı dostu / uyumludur, çünkü sondaki yeni satırın olmaması çeşitli durumlarda ek zorluklar ekleyebilir (birden fazla metin dosyasını birleştirme / yazdırma, tipik komut satırı araçlarıyla ayrıştırma, busybox's vi, vb. gibi minimum editörler ).
mtraceur

(1) VMS'den önce, RT-11 RSX-11 TOPS-10 dosya sistemlerine sadece bir blok için hassastır ve bir EOF karakteri gerekir. Görünüşe göre DEC'den kopyalayan ve sırayla erken MS-DOS tarafından kopyalanan ve daha sonra Windows'a aktarılan CP / M de öyle. (2) Unix'te, insanlar genellikle tty cihazlarında mermi çalıştırmasına rağmen, JohanM tarafından daha ayrıntılı olarak açıklandığı gibi, kabuk değil tty sürücüsüdür .
dave_thompson_085

Elbette - DEC oradaydı (ve eski sürümlerden bahsettiğimi unutmayın ). O olup olmadığı kökenli CP / M özelliği (burada) keşfetmek için ilginç bir konu olacağını; Alternatiflerden biraz bahsetmek için bu davalardan bahsettim.
Thomas Dickey

7

EOF bir karakter değil. Bir dosya akışından okunacak başka karakter olmadığını gösteren bir durumdur. Terminalden EOF komutunu girdiğinizde, işletim sistemine özel bir karakter koymak yerine giriş akışını kapatması için sinyal verirsiniz.


1
Evet ama ASCII tablosunda EOF 26'dır, bu yüzden son baytın 26 ikili gösterimi olduğunu düşündüm. Peki bir girdiyi okuyan bir program nerede bittiğini nasıl bilebilir?
sworwitz

ASCII, bilginin bir ağ üzerinden aktarılması içindir. Bu durumda, bir EOF karakterine ihtiyacınız vardır. (ASCII'nin de çok fazla kontrol kodu vardı. Her şey yazdırılamaz.) Dosya akışları durumunda, dosyanın boyutu dosya sistemi aracılığıyla zaten bilinir, böylece işletim sistemi okunacak daha fazla veri kalmadığını söyleyebilir.
Munir

@sworwitz: C ile ilgili olarak, arama başına karakter döndüren giriş okuma işlevleri karakter değil, int (genellikle 32 bit sayı, ancak en az 16 bit olmalıdır) döndürür. İşlev sinyalleri ve EOF, geçerli bir 8 bit değeri olmayan -1 (0xffffffff) döndürerek 0xff değil, herhangi bir ASCII karakteriyle karıştırılmayacaktır. Bir dize döndüren işlevler de okunan verinin uzunluğunu döndürür. Bu uzunluk hiçbir veriyi veya veri sonunu belirtmek için kullanılabilir (yine uzunluk -1 olabilir). Son olarak, bir akışın sonuna ulaşıp ulaşmadığını söyleyebileceğiniz bir işlev de var
Slebetman

Tamam teşekkürler! Bash'da Ctrl + d tuşlarına bastığımda ASCII karakterini giriyorum, değil mi?
sworwitz

@sworwitz Tam olarak değil. bashEllerini girişe almadan önce TTY sürücüsü tarafından masaj yapılır. Bu sürücü Ctrl-D'yi durdurur ve bash (EOF'un bir karakter değil, özel bir dosya durumu olduğu yerlerde) bir EOF gönderir
Stig Hemmer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.