gpt4 book ai didi

c++ - 发送/获取结构时使用 streambuf

转载 作者:行者123 更新时间:2023-11-28 04:54:54 28 4
gpt4 key购买 nike

我正在研究 boost::asio::streambuf 并发现我可以使用它发送/获取一个结构,但是当我发送一个结构时我无法获取它我已经发送了。文档说应该使用 commit()consume(),但是我应该在哪里使用它们呢?

struct person
{
int m_id;
std::string m_message;
};

std::istream& operator>>(std::istream& in, struct person& p)
{
return in >> p.m_id >> p.m_message;
}

std::ostream& operator<<(std::ostream& out, struct person& p)
{
return out << p.m_id << " " << p.m_message;
}

int main()
{
boost::asio::streambuf buf;
std::ostream out(&buf);

person p;

p.m_id = 1;
p.m_message = "Hello World!";

out << p;

std::istream in(&buf);

person p1;

in >> p1;

cout << "ID: " << p1.m_id << endl;
cout << "Message: " << p1.m_message << endl;

return 0;
}

问题出在字符串上,所以当我只输入“hello”(没有 world)时,它工作正常,但如果我添加“world!”如上所示,它只是没有看到添加的“world!”,为什么?

最佳答案

有很多问题。

  1. 首先,尽可能使参数const&:

    std::ostream &operator<<(std::ostream &out, person const &p) {
  2. 其次,确保流刷新到缓冲区。我认为限制 ostreamistream 实例的生命周期是个好习惯

  3. 第三,选择稳健的格式。当您有 m_id = 1m_message = "123" 时,您的示例已经有更大的问题(您能看到吗?)。

    在文本格式中,您需要固定长度的字段或定界协议(protocol)。让我们修复它:

    std::ostream &operator<<(std::ostream &out, person const &p) {
    return out << p.m_id << ";" << p.m_message.length() << ";" << p.m_message;
    }

    现在,当你回头读它时,你会发现你需要更加精确:

    std::istream &operator>>(std::istream &in, person &p) {
    char separator;
    size_t length;

    bool ok = in >> p.m_id
    && in >> separator && separator == ';'
    && in >> length
    && in >> separator && separator == ';'
    ;

    if (ok) {
    p.m_message.resize(length);
    in.read(&p.m_message[0], length);

    p.m_message.resize(in.gcount());
    }

    // ensure the expected number of bytes were read
    ok = ok && (p.m_message.length() == length);

    if (!ok)
    in.setstate(std::ios::failbit);

    return in;
    }

    哎呀。真的吗?对真的。至少!

  4. 做错误处理

完整演示

Live On Coliru

#include <boost/asio.hpp>
#include <iostream>

struct person {
int m_id;
std::string m_message;
};

std::ostream &operator<<(std::ostream &out, person const &p) {
return out << p.m_id << ";" << p.m_message.length() << ";" << p.m_message;
}

std::istream &operator>>(std::istream &in, person &p) {
char separator;
size_t length;

bool ok = in >> p.m_id
&& in >> separator && separator == ';'
&& in >> length
&& in >> separator && separator == ';'
;

if (ok) {
p.m_message.resize(length);
in.read(&p.m_message[0], length);

p.m_message.resize(in.gcount());
}

// ensure the expected number of bytes were read
ok = ok && (p.m_message.length() == length);

if (!ok)
in.setstate(std::ios::failbit);

return in;
}

int main() {
boost::asio::streambuf buf;

std::ostream(&buf) << person{ 1, "Hello World!" };

person received;
if (std::istream(&buf) >> received) {
std::cout << "ID: " << received.m_id << std::endl;
std::cout << "Message: " << received.m_message << std::endl;
} else {
std::cout << "Couldn't receive person\n";
}
}

打印

ID:      1
Message: Hello World!

奖金

C++14 添加了std::quoted:

#include <iomanip>
std::ostream &operator<<(std::ostream &out, person const &p) { return out << p.m_id << std::quoted(p.m_message); }
std::istream &operator>>(std::istream &in, person &p) { return in >> p.m_id >> std::quoted(p.m_message); }

在这种情况下,它也可以完成工作: Live On Coliru

关于c++ - 发送/获取结构时使用 streambuf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47396576/

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