簡體   English   中英

用C ++將結構寫入字符串流

[英]Writing a struct into a stringstream in C++

我有一些結構:

struct dHeader
{
    uint8_t    blockID;
    uint32_t   blockLen;
    uint32_t   bodyNum;
};
struct dBody
{
    char       namestr[10];
    uint8_t    blk_version;
    uint32_t   reserved1;
}

我有一個字符串流為:

std::stringstream Buffer(std::iostream::in | std::iostream::out);

我想寫一個dHdr和多個dBody結構到Buffer與

Buffer << Hdr1;
Buffer << Body1;
Buffer << Body1;

我得到錯誤:

錯誤:“緩沖區<< Hdr1”中的“ operator <<”不匹配

如果我嘗試使用:

Buffer.write(reinterpret_cast<char*>(&Hdr1), sizeof(dbHdr1));
Buffer.write(reinterpret_cast<char*>(&Body1), sizeof(Body1));
Buffer.write(reinterpret_cast<char*>(&Body2), sizeof(Body2));

我對打包和內存對齊感到困惑。

  • 將結構寫入字符串流的最佳方法是什么?
  • 並將stringstream讀取為常規字符串?

對於每個結構,您都需要定義類似於以下內容的內容:

struct dHeader
{
    uint8_t    blockID;
    uint32_t   blockLen;
    uint32_t   bodyNum;
};

std::ostream& operator<<(std::ostream& out, const dHeader& h)
{
     return out << h.blockID << " " << h.blockLen << " " << h.bodyNum;
}

std::istream& operator>>(std::istream& in, dHeader& h) // non-const h
{
    dHeader values; // use extra instance, for setting result transactionally
    bool read_ok = (in >> values.blockID >> values.blockLen >> values.bodyNum);

    if(read_ok /* todo: add here any validation of data in values */)
        h = std::move(values);
    /* note: this part is only necessary if you add extra validation above
    else
        in.setstate(std::ios_base::failbit); */
    return in;
}

(其他結構類似)。

編輯:無緩沖的讀/寫實現具有以下缺點:

  • 它是未格式化的; 如果您控制着小型實用程序的編譯和運行位置,那么這可能不是問題,但是通常,如果您獲取序列化數據並在不同的體系結構上運行/編譯該應用程序,則字節序會出現問題。 您還需要確保使用的類型不依賴於體系結構(即繼續使用uintXX_t類型)。

  • 它很脆; 實現取決於僅包含POD類型的結構。 如果稍后將char *添加到結構中,則代碼將進行相同的編譯,只顯示未定義的行為。

  • 它是晦澀的(代碼的客戶可能希望看到為I / O定義的接口,或者假定您的結構不支持序列化)。 通常,沒有人認為“也許我可以序列化,但可以使用無緩沖的I / O”-至少在作為自定義結構或類實現的客戶端時不會。

這些問題可以得到改善,通過添加I / O流的運營商,在無緩沖讀取和寫入方面實現。

上面的運算符的示例代碼:

std::ostream& operator<<(std::ostream& out, const dHeader& h)
{
     out.write(reinterpret_cast<char*>(&h), sizeof(dHeader));
     return out;
}

std::istream& operator>>(std::istream& in, dHeader& h) // non-const h
{
    dHeader values; // use extra instance, for setting result transactionally
    bool read_ok = in.read( reinterpret_cast<char*>(&values), sizeof(dHeader) );

    if(read_ok /* todo: add here any validation of data in values */)
        h = std::move(values);
    /* note: this part is only necessary if you add extra validation above
    else
        in.setstate(std::ios_base::failbit); */
    return in;
}

這將代碼集中在接口后面(即,如果您的類不再支持無緩沖寫入,則您將不得不在一個位置更改代碼),並使意圖顯而易見(對結構實現序列化)。 它仍然很脆,但不那么脆弱。

您可以為std::ostream::operator<<類似提供重載

std::ostream& operator<<(std::ostream&, const dHeader&);
std::ostream& operator<<(std::ostream&, const dBody&);

有關更多信息,請參見此stackoverflow問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM