在 C++ 中从文件中读取行的首选模式是什么?
我在 C++ 教程中至少见过两种从文件中读取行的方法:
I've seen at least two ways of reading lines from a file in C++ tutorials:
std::ifstream fs("myfile.txt");
if (fs.is_open()) {
while (fs.good()) {
std::string line;
std::getline(fs, line);
// ...
和:
std::ifstream fs("myfile.txt");
std::string line;
while (std::getline(fs, line)) {
// ...
当然,我可以添加一些检查以确保文件存在并已打开.除了异常处理之外,是否有理由更喜欢更详细的第一个模式?您的标准做法是什么?
Of course, I can add a few checks to make sure that the file exists and is opened. Other than the exception handling, is there a reason to prefer the more-verbose first pattern? What's your standard practice?
推荐答案
while (std::getline(fs, line))
{}
这不仅是正确的,而且也更可取 因为它是惯用的.
This is not only correct but preferable also because it is idiomatic.
我假设在第一种情况下,您没有在 std::getline()
之后检查 fs
作为 if(!fs) break;
代码> 或等效的东西.因为如果你不这样做,那么第一种情况是完全错误的.或者如果你这样做了,那么第二个仍然更可取,因为它在逻辑上更简洁明了.
I assume in the first case, you're not checking fs
after std::getline()
as if(!fs) break;
or something equivalent. Because if you don't do so, then the first case is completely wrong. Or if you do that, then second one is still preferable as its more concise and clear in logic.
函数 good()
应该在您尝试从流中读取之后 使用;它用于检查尝试是否成功.在你的第一种情况下,你不这样做.在 std::getline()
之后,你假设读取成功,甚至没有检查 fs.good()
返回什么.此外,您似乎假设如果 fs.good()
返回 true,std::getline
将成功从流中读取一行.您正朝着相反的方向前进:事实是,如果 std::getline
从流中成功读取一行,则 fs.good()
将返回真
.
The function good()
should be used after you made an attempt to read from the stream; its used to check if the attempt was successful. In your first case, you don't do so. After std::getline()
, you assume that the read was successful, without even checking what fs.good()
returns. Also, you seem to assume that if fs.good()
returns true, std::getline
would successfully read a line from the stream. You're going exactly in the opposite direction: the fact is that, if std::getline
successfully reads a line from the stream, then fs.good()
would return true
.
cplusplus 上的文档说明了 good()
那个,
The documentation at cplusplus says about good()
that,
如果没有设置流的任何错误标志(eofbit、failbit 和 badbit),则该函数返回 true.
The function returns true if none of the stream's error flags (eofbit, failbit and badbit) are set.
也就是说,当您尝试从输入流中读取数据时,如果尝试失败,则只会设置失败标志并且 good()
返回 false
作为失败的指示.
That is, when you attempt to read data from an input stream, and if the attempt was failure, only then a failure flag is set and good()
returns false
as an indication of the failure.
如果你想限制 line
变量的作用域只在循环内部,那么你可以写一个 for
循环为:
If you want to limit the scope of line
variable to inside the loop only, then you can write a for
loop as:
for(std::string line; std::getline(fs, line); )
{
//use 'line'
}
注意:在阅读@john 的解决方案后,我想到了这个解决方案,但我认为它比他的版本更好.
Note: this solution came to my mind after reading @john's solution, but I think its better than his version.
在此处阅读详细说明,为什么第二个更可取且符合地道:
Read a detail explanation here why the second one is preferable and idiomatic:
- Linux |C++ 中的分段错误 - 由于函数 ifstream
或者阅读@Jerry Coffin 写得很好的博客:
Or read this nicely written blog by @Jerry Coffin:
- 阅读文件
相关文章