gpt4 book ai didi

c++ - 在 C++ 中将结构写入字符串流

转载 作者:搜寻专家 更新时间:2023-10-31 00:35:25 25 4
gpt4 key购买 nike

我有一些结构:

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;

我得到错误:

error: no match for 'operator<<' in 'Buffer << Hdr1'

如果我尝试:

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

我对打包和内存对齐感到困惑。

  • 将结构写入字符串流的最佳方法是什么?
  • 并阅读将字符串流转换为常规字符串?

最佳答案

对于您的每个结构,您需要定义类似于此的内容:

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 定义的接口(interface),或者假设您的结构不支持序列化)。通常,没有人认为“也许我可以序列化,但使用无缓冲的 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;
}

这集中了接口(interface)后面的代码(即,如果您的类不再支持无缓冲写入,您将不得不更改一个地方的代码),并使您的意图显而易见(为你的结构)。它仍然很脆,但不那么脆了。

关于c++ - 在 C++ 中将结构写入字符串流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23905335/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com