提问人:gnikit 提问时间:6/3/2018 最后编辑:gnikit 更新时间:6/3/2018 访问量:1953
getline 设置 failbit 以及 eof
getline setting failbit along with eof
问:
我知道这种行为的起源,因为它在 SO 的多篇文章中得到了很好的解释,一些值得注意的例子是:
为什么循环条件中的 iostream::eof 被认为是错误的?
它也包含在 std::getline
标准中:
3) 如果出于任何原因没有提取任何字符(甚至没有提取丢弃的分隔符),getline 将设置 failbit 并返回。
我的问题是如何处理这种行为,您希望您的流捕获所有情况的异常,但通过到达最后一行为空的文件引起的异常除外。我是否遗漏了什么明显的内容?failbit
eof
一个 MWE:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
void f(const std::string & file_name, char comment) {
std::ifstream file(file_name);
file.exceptions(file.failbit);
try {
std::string line;
while (std::getline(file, line).good()) {
// empty getline sets failbit throwing an exception
if ((line[0] != comment) && (line.size() != 0)) {
std::stringstream ss(line);
// do stuff
}
}
}
catch (const std::ios_base::failure& e) {
std::cerr << "Caught an ios_base::failure.\n"
<< "Explanatory string: " << e.what() << '\n'
<< "Error code: " << e.code() << '\n';
}
}
int main() {
f("example.txt", '#');
}
其中 example.txt 是制表符分隔的文件,其最后一行仅是字符:\n
# This is a text file meant for testing
0 9
1 8
2 7
编辑:
while(std::getline(file, line).good()){...}
复制问题。
答:
编辑:我误解了OP,请参阅上面David的回答。此答案用于检查文件是否具有终止换行符。
在循环结束时,检查 .while (getline)
file.eof()
假设您刚刚对文件中的最后一行执行了操作。std::getline()
如果后面有分隔符,则已读取分隔符并且没有设置 .(在这种情况下,下一个将设置 。
\n
std::getline()
eofbit
std::getline()
eofbit
而如果没有,则已读取 EOF 并设置了 .
\n
std::getline()
eofbit
在这两种情况下,下一个都将触发并输入异常处理程序。std::getline()
failbit
PS:如果为空,则该行为 UB。条件的顺序需要颠倒。if ((line[0] != comment) && (line.size() != 0)) {
line
评论
file.eof()
peek()
getline()
eofbit
file.eof()
basic_ios::clear: iostream erro
iostream:1
getline
eofbit
getline
failbit
getline
eofbit
failbit
f.eof()
避免设置的另一种方法是简单地重构测试以检测空行的读取。由于这是本例中的最后一行,因此您可以简单地避免抛出错误,例如:failbit
if
return
std::ifstream file (file_name);
file.exceptions (file.failbit);
try {
std::string line;
while (std::getline(file, line)) {
// detect empty line and return
if (line.size() == 0)
return;
if (line[0] != comment) {
std::stringstream ss(line);
// do stuff
}
}
}
...
您的另一种选择是检查是否设置在 .如果已设置 -- 读取成功完成。例如eofbit
catch
eofbit
catch (const std::ios_base::failure& e) {
if (!file.eof())
std::cerr << "Caught an ios_base::failure.\n"
<< "Explanatory string: " << e.what() << '\n'
<< "Error code: " /* << e.code() */ << '\n';
}
评论
line.size()==0
std::getline(file,line)
getline
failbit
while
if (line.size() != 0)
getline
'\n'
'\n'
line
gcount = 1
eofbit
failbit
line.size() = 0
'\n'
:)
line[0] != comment
line.size() != 0
if (!file.eof())
catch
line[0] != comment
line
line.size() != 0 && line[0] != comment
评论