2015-05-12 150 views
5

我正在測試如何從std::streamstring中讀取數據,但是我發現它錯了,有誰能指出有什麼問題?並給出一個正確的方式來閱讀它?從字符串流中讀取內容

我的測試代碼是:

#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; 
} 

而且我得到的輸出:

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 

--- 

正如你可能會注意到最後的讀操作只讀取5個字符留出最後兩個「AM '儘管它應該能夠讀取它。我是否缺少Somtehing?

+0

我認爲你需要使用'wchar_t'版本的流和字符串。 – Nawaz

+1

用常規的'o'代替'ó'結果相同。爲什麼我需要使用'wchar_t'呢? –

+1

我將你的代碼複製到一個.cpp文件中,並使用g ++編譯而沒有參數。在我的機器上,整個流的打印沒有截斷,但第一次只讀取一個字符。我使用gcc 4.9.2和glibc 2.21-3。 –

回答

3

其實,​​也只讀過立即available characters,什麼是取決於平臺,所以它也允許返回0,同時還存在着流和後續調用很可能返回缺少的字符的字符。 要獲取所有可用數據,我寧願使用readgcount組合以獲取您閱讀的字符數。

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); 

只是爲了澄清:
雖然我相信,你觀察到的behavoir由標準允許的,我不明白爲什麼要執行這樣的表現時,輸入流是基於一個字符串(我不熟悉流的實現細節)。你可以檢查的是,如果read實際上對應於rdbuf()->in_avail(),並且如果它不這可能確實是一個編譯器錯誤。

+0

通過改變來解決問題。所以'readsome'應該以彙集的方式使用? (因爲可能會返回0個事件,儘管還有內容)。 –

+0

@Javier先生:我真的不知道。據我所知,背後的思想是給你所有可用的字符,而沒有可能阻止系統調用。所以我不確定如果你會得到所有的數據。另一方面,我也不明白,爲什麼VC++ 2008的具體實現不會給你一個本地字符串對象的所有數據。但是,如果您正在討論線程池,那麼我肯定會說不,因爲它不是線程安全的,所以您將不得不序列化它。 – MikeMB

+0

是的我的意思是單線程連續調用。我明白'readsome'儘可能少的目的。然而,我測試了將do-while條件改爲'!ss.eof()',顯然'readsome'從不讀取整個流,也檢查了'in_avail'並以50的值開始,並且在每次調用中都沒有讀取最後一個。謝謝。 –