我正在使用qtestlib,C ++(clang LLVM 8.0版)编写文件读取的单元测试。我有以下代码逐行读取文件。
std::ifstream infile;
try {
infile.open(path.c_str());
std::ios_base::iostate exceptionMask = infile.exceptions() | std::ios::failbit;
infile.exceptions(exceptionMask);
} catch (std::ios_base::failure& e) {
// print the exception
qDebug() << "Exception caught: " << QString::fromStdString(e.what());
}
try {
std::string line;
while (std::getline(infile, line)) {
// print the line
qDebug() << QString::fromStdString(line);
}
} catch (std::ios_base::failure& e) {
qDebug() << "Exception caught: " << QString::fromStdString(e.what());
}
问题:
上面的代码读取文件中的所有行并打印出来。但是在打印完最后一行后,它会抛出异常并打印以下内容,
捕获异常:“basic_ios :: clear”
我跟着很多线程,但找不到解决方案。为什么我会收到此错误?
答案 0 :(得分:1)
阅读并打印完所有行后,while (std::getline(infile, line))
仍会尝试读取另一行。如果它完全失败 - 读取零字符 - 它会设置failbit
以表示其失败。
错误消息的奇怪部分是,尽管名称如此,basic_ios::clear
可用于设置失败位,如果您使用exceptions
启用了相同的位,也会引发异常。
答案 1 :(得分:1)
查看std::getline的文档。设置标志的场景:
failbit
获得的输入无法解释为此类对象的有效文本表示。在这种情况下, distr 保留调用前的参数和内部数据。请注意,某些 eofbit 案例也会设置 failbit 。
最后一句话有点模糊,但可以解释观察到的行为。
我做了一些实验并找到了模式。首先,我以这种方式纠正了您的代码:
try {
std::string line;
while (std::getline(infile, line)) {
// print the line
qDebug() << QString::fromStdString(line);
if (infile.eof()) {
return;
}
}
} catch (std::ios_base::failure& e) {
qDebug() << "Exception caught: " << QString::fromStdString(e.what());
}
现在如果输入文件以空行结束,我会得到一个例外,如果最后一行没有以&#34; \ n&#34;结束。 return
打破了循环。
如果您尝试读取已经到达流末尾的流,则设置 falbit 。 没有&#34;如果&#34;检查你是否总是这样阅读并总是得到例外。
对于最后一行空,我有一些线索,但不知道如何很好地解释它。首先要检查其他平台/编译器的行为。