2015-05-12 35 views
5

std::streamstring'dan verileri nasıl okuyacağımı test ediyordum, ancak yanlış anladım, sorunun ne olduğunu işaret edebilir mi? ve okumak için doğru bir yol?Dize akışından içeriği okuma

#include <iostream> 
#include <string> 
#include <sstream> 

#define BUFFER_SIZE 16 

int main(int argc, char ** argv) 
{ 

    std::stringstream ss; 
    ss << "Un texto con datos de ejemplo para probar la extacción de un stream"; 

    std::cout << "Stream contents: '" << ss.str() << "'" << std::endl; 

    char buffer[BUFFER_SIZE] = {0}; 

    std::streamsize read = 0; 

    do { 
     read = ss.readsome(buffer, BUFFER_SIZE - 1); 
     std::cout << "Read: " << ss.gcount() << std::endl; 
     std::cout << buffer << std::endl; 
     std::cout << "---" << std::endl; 
     std::fill(buffer, buffer + BUFFER_SIZE, 0); 
    } while (read > 0); 

    return 0; 
} 

Ve çıktı alıyorum::

Benim test kodudur

Stream contents: 'Un texto con datos de ejemplo para probar la extacci¾n de un stream' 
Read: 15 
Un texto con da 
--- 
Read: 15 
tos de ejemplo 
--- 
Read: 15 
para probar la 
--- 
Read: 15 
extacci¾n de un 
--- 
Read: 5 
stre 
--- 
Read: 0 

--- 

son okuma işlemi son iki 'am dışarıda bırakarak sadece 5 karakter okur fark edebilirsiniz gibi 'onu okuyabilmiş olsa bile. Ben somtehing eksik miyim?

+0

Sanırım "wchar_t" akışları ve dizeleriyle çalışmanız gerekiyor. – Nawaz

+1

'ó 'ile düzenli bir' o' değiştirilmesi, aynı sonuçla sonuçlanır. Niçin 'wchar_t' ile çalışmalıyım? –

+1

Kodunuzu bir .cpp dosyasına kopyaladım ve argüman olmadan g ++ kullanarak derledim. Makinemde, tüm akış kesilmeden yazdırılır, ancak ilk okunma sadece bir karakteri alır. Gcc 4.9.2 ve glibc 2.21-3 kullanıyorum. –

cevap

3

Aslında readsome sadece hemen available characters ve ne olduğunu platforma bağlıdır okumak, bu yüzden de hala dere ve muhtemelen eksik karakterleri geri dönebilirler sonraki çağrısında karakterler varken 0 dönmesine izin verilir. Kullanılabilir tüm verileri almak için, gcount ile birlikte okuduğunuz karakter sayısını almak için read'u kullanmayı tercih ederim.

do { 
    ss.read(buffer, BUFFER_SIZE - 1); 
    read=ss.gcount(); 
    std::cout << "Read: " << ss.gcount() << std::endl; 
    std::cout << buffer << std::endl; 
    std::cout << "---" << std::endl; 
    std::fill(buffer, buffer + BUFFER_SIZE, 0); 
} while (read > 0); 

Sadece açıklama: Uygulama giriş akışı, bir dizgi dayandığında bu şekilde davranmaya neden
inanıyorum ederken, gözlenen behavoir standardına göre izin verilir , ben (görmüyorum Akımların uygulama detaylarına aşina değilim). Ne kontrol edebilirsiniz, read aslında rdbuf()->in_avail()'a karşılık geliyorsa ve eğer bu gerçekten derleyici bir hata olabilir.

+0

Bu değişikliği yapmak sorunu çözüyor. Yani 'readsome' bir havuz şeklinde kullanılmalıdır? (Çünkü içerik kalsa da 0 olayı döndürebilir). –

+0

@Javier Mr: Gerçekten bilmiyorum. Anlayabildiğim kadarıyla, arkasındaki fikir, potansiyel olarak engelleyen bir sistem çağrısı olmadan mevcut olan tüm karakterleri size vermektir. Bu yüzden emin değilim ki tüm verileri alırsanız. Öte yandan, VC++ 2008'in belirli bir uygulamasının neden yerel bir dize nesnesindeki tüm verileri vermediğini de anlamıyorum. Ancak iplik havuzlarından bahsediyorsanız, kesinlikle threadafe olmadığı için kesinlikle hayır diyeyim, bu yüzden onu seri hale getirmelisiniz. – MikeMB

+0

Evet, tek sıralı ardışık çağrıları kastettim. "Okuma" amacının mümkün olduğunca azını engellemesini anlıyorum. Ancak do-while koşulunu '! Ss.eof() olarak değiştirmeyi test ettim ve görünüşe göre 'readsome' tüm akışı hiç okumaz, in_avail'i de kontrol etti ve 50'lik bir değerle başlar ve her çağrıda hiç okumadan düşüş olur son olanlar. Teşekkürler. –

İlgili konular