在C++中从文件中读取行的首选模式是什么?

jda*_*jda 17 c++ file-io

我在C++教程中至少看到过两种从文件中读取行的方法:

std::ifstream fs("myfile.txt");
if (fs.is_open()) {
  while (fs.good()) {
    std::string line;
    std::getline(fs, line);
    // ...
Run Code Online (Sandbox Code Playgroud)

和:

std::ifstream fs("myfile.txt");
std::string line;
while (std::getline(fs, line)) {
  // ...
Run Code Online (Sandbox Code Playgroud)

当然,我可以添加一些检查以确保文件存在并打开.除了异常处理之外,是否有理由更喜欢更详细的第一种模式?你的标准做法是什么?

Naw*_*waz 25

while (std::getline(fs, line))
{}
Run Code Online (Sandbox Code Playgroud)

这不仅是正确的,而且也是优选的, 因为它是惯用的.

我假设在第一种情况下,你不检查fsstd::getline()作为if(!fs) break;或等价的东西.因为如果你不这样做,那么第一种情况就完全错了.或者如果你这样做,那么第二个仍然是优选的,因为它更简洁和清晰的逻辑.

尝试从流中读取good()应使用该函数; 它用于检查尝试是否成功.在你的第一种情况下,你不这样做.之后,您认为读取成功,甚至没有检查返回的内容.此外,您似乎假设如果返回true,将成功从流中读取一行.你正朝着相反的方向前进:事实是,如果从流中成功读取一行,那么就会返回.std::getline()fs.good()fs.good()std::getlinestd::getlinefs.good()true

cplusplus的文档说明了good()这一点,

如果没有设置流的错误标志(eofbit,failbit和badbit),则该函数返回true.

也就是说,当您尝试从输入流中读取数据时,如果尝试失败,则只会设置失败标志并good()返回false以指示失败.

如果要将line变量的范围仅限制在循环内部,则可以将for循环写为:

for(std::string line; std::getline(fs, line); )
{
   //use 'line'
}
Run Code Online (Sandbox Code Playgroud)

注意:在阅读@ john的解决方案后,我想到了这个解决方案,但我认为它比他的版本更好.


在这里阅读详细解释为什么第二个更好和惯用:

或者阅读@Jerry Coffin撰写的精美博客: