我在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)
这不仅是正确的,而且也是优选的, 因为它是惯用的.
我假设在第一种情况下,你不检查fs
后std::getline()
作为if(!fs) break;
或等价的东西.因为如果你不这样做,那么第一种情况就完全错了.或者如果你这样做,那么第二个仍然是优选的,因为它更简洁和清晰的逻辑.
尝试从流中读取后good()
应使用该函数; 它用于检查尝试是否成功.在你的第一种情况下,你不这样做.之后,您认为读取成功,甚至没有检查返回的内容.此外,您似乎假设如果返回true,将成功从流中读取一行.你正朝着相反的方向前进:事实是,如果从流中成功读取一行,那么就会返回.std::getline()
fs.good()
fs.good()
std::getline
std::getline
fs.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撰写的精美博客: