考虑以下代码:
#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
终止程序。
全球开发银行报告:
gdb: unknown target exception 0x80000001 at 0x7ff909e845c0
Thread 1 received signal ?, Unknown signal.
0x00007ff909e845c0 in ?? ()
但是,仍然没有结束,。如果我将文件内容更改为包含以下任一内容:
0 0
或
0 0 0 0
0 0 0 0
输出再次如愿以偿(使用原始代码-- read_data()
中的一个cout
和main()
中的一个)。
为了确保我没有被某个无法打印的字符骗到我的文件中,我使用PowerShell输出它的十六进制表示,这导致了关于原始文件内容的以下序列:
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。
发布于 2019-03-17 15:34:14
这是一个本地的:
std::stringstream training{};
这将返回对上述本地的引用,用元组包装:
return std::tie(training);
因此,auto [train] = ...;
将名称train
初始化为悬空引用。程序的行为未定义。
如果您需要返回两个流(或更多),那么只需将它们放在您选择的元组/数组/自定义聚合中:
#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';
}
活码
复制省略保证额外的对象要么被完全移除,要么被构造到位。
https://stackoverflow.com/questions/55208725
复制相似问题