2013-02-25 91 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