2013-02-25 94 views
1

我有以下代碼試圖讀/寫一個無符號的int和一個std :: wstring到std :: stringstream。二進制讀/寫到std :: stringstream

#include <memory> 
#include <iostream> 
#include <vector> 
#include <sstream> 

class SerializationException : public std::runtime_error 
{ 
public: 
    SerializationException(const char* msg) : std::runtime_error(msg) { } 
}; 

class Serialization 
{ 
public: 
    static void Write(std::ostream& stream, const std::wstring& item) 
    { 
     Write(stream, eStdWString); 
     Write(stream, item.length()); 
     stream.write(reinterpret_cast< const char* >(item.c_str()), item.length()); 
    } 

    static std::wstring ReadWString(std::istream& stream) 
    { 
     const unsigned int type = ReadUInt32(stream); 
     if (type != eStdWString) 
     { 
      throw SerializationException("Expected eStdWString"); 
     } 
     const unsigned int length = ReadUInt32(stream); 
     std::vector<wchar_t> tmpBuf(length); 
     stream.read(reinterpret_cast< char* > (tmpBuf.data()), length); 
     return std::wstring(tmpBuf.begin(), tmpBuf.end()); 
    } 

    static void Write(std::ostream& stream, const unsigned int& item) 
    { 
     const unsigned int type = eUInt32; 
     stream.write(reinterpret_cast< const char* >(&type), sizeof(type)); 
     stream.write(reinterpret_cast< const char* >(&item), sizeof(item)); 
    } 

    static unsigned int ReadUInt32(std::istream& stream) 
    { 
     const unsigned int type = 0; 
     stream.read(reinterpret_cast< char* > (type), sizeof(type)); 
     if (type != eUInt32) 
     { 
      throw SerializationException("Expected eUInt32"); 
     } 
     const unsigned int tmp = 0; 
     stream.read(reinterpret_cast< char* > (tmp), sizeof(tmp)); 
     return tmp; 
    } 

private: 
    enum eTlvBlockTypes 
    { 
     eStdWString, 
     eUInt32 
    }; 
}; 

int main(int, char**) 
{ 
    std::wstring myStr = L"HelloWorld!"; 
    int myInt = 0xdeadbeef; 

    try 
    { 
     std::stringstream ss(std::ios_base::out | std::ios_base::in | std::ios_base::binary); 
     Serialization::Write(ss, myStr); 
     Serialization::Write(ss, myInt); 

     myInt = Serialization::ReadUInt32(ss); 
     myStr = Serialization::ReadWString(ss); 
    } 
    catch (const std::runtime_error& ex) 
    { 
     std::cout << ex.what() << std::endl; 
    } 
    return 0; 
} 

但是在回讀數據流,我得到一個斷言失敗,因爲流是NULL,有人可以解釋這是爲什麼,以及如何解決它?

編輯:斷言失敗是ReadUInt32()的第二行。

stream.read(reinterpret_cast< char* > (type), sizeof(type)); 
+0

哪裏斷言失敗?更新/編輯了 – jrok 2013-02-25 15:26:50

+0

。 – paulm 2013-02-25 15:29:05

+2

我會注意的一件事是你寫了一個字符串和一個int,然後你讀回一個int和一個字符串。我認爲你有一個倒退。 – 2013-02-25 15:29:53

回答

4

你需要解決這個問題:

stream.read(reinterpret_cast< char* > (type), sizeof(type)); 

這樣:

stream.read(reinterpret_cast< char* > (&type), sizeof(type)); 

這再次說明,reinterpret_cast的危險

+0

你會建議什麼在這種情況下避免使用它? – paulm 2013-02-25 15:59:34

+0

不幸的是有時它是不可避免的。在這種情況下,我認爲它們應該在std :: basic_istream :: read中使用void *而不是char *,至少它會有助於防止這種情況。 – Slava 2013-02-25 16:05:55