将此视为对 Nawaz 已经非常出色的答案的扩展评论。
关于您的第一个选项,
while (fs.good()) {
std::string line;
std::getline(fs, line);
...
这有多个问题。第一个问题是while 条件在错误的位置并且是多余的。它在错误的位置,因为fs.good() 指示最近对文件执行的操作是否正常。一段时间条件应该是关于即将到来的动作,而不是之前的动作。无法知道即将对文件执行的操作是否正常。即将采取什么行动? fs.good() 不会读取您的代码来查看即将执行的操作。
第二个问题是您忽略了来自std::getline() 的返回状态。如果您立即使用fs.good() 检查状态,那没关系。所以,稍微修正一下,
while (true) {
std::string line;
if (std::getline(fs, line)) {
...
}
else {
break;
}
}
或者,您可以使用if (! std::getline(fs, line)) { break; },但现在您在循环中间有一个break。叶赫。如果可能的话,让退出条件成为循环语句本身的一部分会好得多。
比较一下
std::string line;
while (std::getline(fs, line)) {
...
}
这是从文件中读取行的标准习语。 C 中存在一个非常相似的习语。这个习语非常古老,使用非常广泛,并且被广泛认为是从文件中读取行的正确方法。
如果您来自一家禁止带有副作用的条件句的商店怎么办? (有很多很多的编程标准都可以做到这一点。)有一种方法可以解决这个问题,而无需使用循环中间的中断方法:
std::string line;
for (std::getline(fs, line); fs.good(); std::getline(fs, line)) {
...
}
不像 break 方法那么难看,但大多数人都会同意这不像标准习语那样好看。
我的建议是使用标准成语,除非某些标准白痴禁止使用它。
附录
关于for (std::getline(fs, line); fs.good(); std::getline(fs, line)):这很丑,有两个原因。一个是明显的重复代码块。
不太明显的是调用getline 然后good 会破坏原子性。如果其他线程也在从文件中读取怎么办?现在这不是很重要,因为 C++ I/O 当前不是线程安全的。它将在即将到来的 C++11 中。仅仅为了让标准的执行者高兴而破坏原子性是灾难的根源。