首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >结构绑定std::元组中断std::std流

结构绑定std::元组中断std::std流
EN

Stack Overflow用户
提问于 2019-03-17 15:31:44
回答 1查看 184关注 0票数 2

考虑以下代码:

代码语言:javascript
运行
复制
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tuple>

auto read_data(std::ifstream& training_file) {
    if (!training_file) {
        throw std::runtime_error{"Error: could not open one or more files"};
    }

    std::stringstream training{};
    training << training_file.rdbuf();

    std::cout << training.str() << '\n';

    return std::tie(training);
}

int main() {
    std::ifstream input{"input.txt"};

    auto [train] = read_data(input);

    std::cout << train.str() << '\n';
    std::cout << "x" << '\n';
}

忽略这样一个事实,即我正在用std::tie返回一个元素(最初,我是两个std::stringstream对象的tie,但这不是MCVE所需要的)。

input.txt文件如下所示:

0,0,0,0,0,0,

注意-在第二行之后是没有中断行。

该程序的意外输出是:

0,0,0,0,0,0,0,0,0,E$~Ź,x

显然,É$~ Ź ,部分不应该存在。

请注意,我输出的文件内容完全相同。我不知道意外的部分是从哪里来的。

在处理代码时,它变得更奇怪了。如果我在main()中注释掉了main()中的std::cout << training.str() << '\n';,并在read_data()函数中复制了std::cout << training.str() << '\n';行,输出将如预期的那样:

0,0,0,0,0,0,0,0,0,0

因此,两次调用std::stringstream::str并不会导致这种情况。它必须由使用返回的值引起。

更重要的是?两次从std::cout << train.str() << '\n';执行main()行将导致使用code 3终止程序。

全球开发银行报告:

代码语言:javascript
运行
复制
gdb: unknown target exception 0x80000001 at 0x7ff909e845c0
Thread 1 received signal ?, Unknown signal.
0x00007ff909e845c0 in ?? ()

但是,仍然没有结束,。如果我将文件内容更改为包含以下任一内容:

代码语言:javascript
运行
复制
0 0

代码语言:javascript
运行
复制
0 0 0 0
0 0 0 0

输出再次如愿以偿(使用原始代码-- read_data()中的一个coutmain()中的一个)。

为了确保我没有被某个无法打印的字符骗到我的文件中,我使用PowerShell输出它的十六进制表示,这导致了关于原始文件内容的以下序列:

代码语言:javascript
运行
复制
30 20 30 20 30 20 30 0D 0A 30 20 30 20 30 20 30

如您所见,我的文件中除了0、空格和carriage-return + line-feed之外,什么都没有。

知道为什么会发生这种事吗?关于详细信息,我使用GCC 8.2.0来自MinGW。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-17 15:34:14

这是一个本地的:

代码语言:javascript
运行
复制
std::stringstream training{};

这将返回对上述本地的引用,用元组包装:

代码语言:javascript
运行
复制
return std::tie(training);

因此,auto [train] = ...;将名称train初始化为悬空引用。程序的行为未定义。

如果您需要返回两个流(或更多),那么只需将它们放在您选择的元组/数组/自定义聚合中:

代码语言:javascript
运行
复制
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <tuple>
#include <array>

auto read_data() {
    std::array<std::stringstream,2> trainings{
        std::stringstream{},
        std::stringstream{}
    };

    return trainings;
}

int main() {

    auto train = read_data();

    std::cout << train[1].str() << '\n';
    std::cout << "x" << '\n';
}

活码

复制省略保证额外的对象要么被完全移除,要么被构造到位。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55208725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档