2016-10-28 50 views
8

Bir akıştaki tüm verileri okuduğumda ancak sonunu okumayı denemediğimde, akımın EOF'si ayarlanmamış. C++ akışları böyle çalışır, değil mi? Bunu ignore() verileri ing eğer yerine read(), EOF ayarlanır,Neden std :: ios_base :: ignore() EOF bitini ayarlıyor?

#include <sstream> 
#include <cassert> 

char buf[255]; 

int main() 
{ 
    std::stringstream ss("abcdef"); 
    ss.read(buf, 6); 

    assert(!ss.eof()); 
    assert(ss.tellg() == 6); 
} 

Ancak: Bu işler sebebidir

#include <sstream> 
#include <cassert> 

int main() 
{ 
    std::stringstream ss("abcdef"); 
    ss.ignore(6); 

    assert(!ss.eof());  // <-- FAILS 
    assert(ss.tellg() == 6); // <-- FAILS 
} 

Bu GCC 4.8 ve GCC gövde (Coliru) üzerindedir.

ne yapıyorum için can sıkıcı olduğu (yani tellg() böyle yapıyor çünkü) Ayrıca tellg() dönüşü -1 yapma talihsiz yan etkisi yoktur.

Bu standart yetkili mi? Eğer öyleyse, hangi pasaj ve neden? ignore() neden anlattığımdan daha fazla okumaya çalışır?

Bu davranış için herhangi bir neden bulamıyorum cppreference's ignore() page. Muhtemelen .seekg(6, std::ios::cur) olabilir, değil mi? Ama hala neler olduğunu bilmek isterim.

+2

Vay, bu MSVS çalışır dönmek yok değil. Ayrıca Coliru'da clang ile başarısız oldu. Derleyici kendisi değil, kütüphane olabileceğini düşünüyorum. – NathanOliver

+0

eof' dışında başka bir 'sınır' belirtirseniz ne olur? – dwcanillas

+0

@dwcanillas: [Değişiklik yok] (http://coliru.stacked-crooked.com/a/bdb33a4a1a87e593). –

cevap

4

Bu bir libstdC++ hatası olduğunu düşünüyorum (42875, h/t NathanOliver). [Istream.unformatted] içinde ignore() ilgili şartlar:

aşağıdakilerden herhangi oluşana kadar

karakterler ekstre edilir:
- n != numeric_limits<streamsize>::max() (18.3.2) ve n karakter kadar
ekstre edilmiştir - uç -of-dosya giriş dizisi üzerinde gerçekleşir (bu durumda fonksiyon ios_base::failure (27.5.5.4) atlayabilir setstate(eofbit), çağırır);
- traits::eq_int_type(traits::to_int_type(c), delim) c mevcut giriş karakteri için c (bu durumda c ayıklanır).
Açıklamalar:traits::eq_int_type(delim, traits::eof()).

yüzden iki koşulu (son göz ardı edilir) var - biz ya n karakterleri okumak veya bir noktadan sonra sona dosya-biz eofbit set bu durumda çarptı. Ancak, bu durumda n karakterini akımdan okuyabiliyoruz (aslında akışınızda 6 karakter var), böylece giriş sırasına dosya sonu vurmayacağız. Libc olarak

++, eof() kurmak ve tellg() 6.

+0

Katıldığına sevindim. :) –

+0

Raporda belirtildiği gibi, gereksinimler libstdC++ içinde bir hatayı açıkça etiketlemek için çok belirsizdir, standartta bir kusur gibi görünüyor. İfadeler, bir uygulamanın ilk olarak EOF'un vurulup vurulmadığını kontrol etmesine ve bundan sonra n 'karakterlerinin daha önceden çıkarılıp çıkarılmadığının kontrol edilmesine olanak sağlar.Ya da 'n' karakterlerinin önceden çıkarılmış olup olmadığını kontrol etmek, EOF'un vurulup vurulmadığını kontrol etmek ve son olarak her iki kontrolün sonucunu birleştirmek. – hvd

+0

@hvd: Muhtemelen. –