2013-05-16 72 views
1

我有stringstream對象。它是通過爲什麼stringstream :: str()會截斷字符串?

stringstream ss; 
boost::iostreams::copy(inp,ss); 

boost::iostreams::filtering_streambuf<boost::iostreams::input> inp; 

填充實際持有中ungzipped文件。

現在,如果我沖洗stringstream的內容與

std::ofstream ofs(path_to_file,std::ios_base::out|std::ios_base::binary); 
ofs << ss.rdbuf(); 

一切文件就可以了。文件填寫完整的正確數據。

但如果我代替沖洗到文件結構字符串這樣

std::string s = ss.str(); 

含量介於中間截斷。它不是一個持久性錯誤,它顯然取決於字符串緩衝區的內容。

內容爲多種語言的HTML文件。

它可能是什麼?謝謝。

+0

由於空終止在這兩種情況下,角色的處理方式不同。 (可能) –

回答

5

你如何確定內容被截斷? A stringstream可以包含空字符,並且std::string s = ss.str()將把空字符及其後面的字符複製到std::string對象。

但是,如果然後使用該治療std::string對象的內容作爲一個C風格的字符串函數,它會出現截斷:

#include <sstream> 
#include <string> 
#include <iostream> 
#include <ostream> 
#include <string.h> 

using namespace std; 

stringstream ss; 

int main() 
{ 
    ss << 'a' << 'b' << 'c' << (char) '\0' << '1' << '2' << '3'; 

    string s = ss.str(); 

    cout << s.size() << endl; 
    cout << s.c_str() << " C string length: " << strlen(s.c_str()) << endl; 
    cout << s << endl; 
} 

產生以下輸出:

7 
abc C string length: 3 
abc 123 
+0

Michael,不需要對''\ 0''的char'進行轉換 - 它已經是一個字符文字。在終端輸出中也值得注意 - 「abc123」沒有明顯的分隔。但是,如果將輸出重定向到文件,則會在十六進制轉儲中看到空值。 (仍然有我upvote)。 –

+0

我可以在調試器中看到該字符串肯定被截斷。 – Alexander

+0

如果你使用的是VS調試器,那麼基本的字符串顯示可能在說謊 - 「std :: string」的調試器顯示(以及作爲.NET字符串對象的FYI)將停止在一個空字符處如果對象包含更多數據。嘗試單步執行我的示例程序 - 雖然s.size()和程序的最後一行清楚地表明有更多,但調試器顯示「s」的值爲「abc」。此外,您可以展開顯示(單擊調試器顯示中變量名旁邊的「+」),它將列出字符串的每個元素(包括空字符)。 –

3

看來你的文件中有空字符符號'\ 0'。這被認爲是字符串的結尾。

+0

這是不正確的:'std :: string'不是空終止的。是的,確實最後一個字符爲空(C兼容),但它允許嵌入式空值。 'strlen(s.c_str())'不一定與's.size()'相同。 –

+0

同意,std :: string不是,但C字符串是以空字符結尾的字符序列 –