Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';从C+;中的文件中读取行的首选模式+;? 我在C++教程中看到了至少两种从文件中读取线条的方法: std::ifstream fs("myfile.txt"); if (fs.is_open()) { while (fs.good()) { std::string line; std::getline(fs, line); // ..._C++_File Io - Fatal编程技术网

什么';从C+;中的文件中读取行的首选模式+;? 我在C++教程中看到了至少两种从文件中读取线条的方法: std::ifstream fs("myfile.txt"); if (fs.is_open()) { while (fs.good()) { std::string line; std::getline(fs, line); // ...

什么';从C+;中的文件中读取行的首选模式+;? 我在C++教程中看到了至少两种从文件中读取线条的方法: std::ifstream fs("myfile.txt"); if (fs.is_open()) { while (fs.good()) { std::string line; std::getline(fs, line); // ...,c++,file-io,C++,File Io,以及: 当然,我可以添加一些检查以确保文件存在并已打开。除了异常处理之外,是否有理由选择更详细的第一种模式?你的标准做法是什么 while (std::getline(fs, line)) {} 这不仅是正确的,而且更可取,因为它是惯用的。 我假设在第一种情况下,如果(!fs)中断,则在std::getline()as之后没有检查fs或类似的东西。因为如果你不这样做,那么第一个案例是完全错误的。或者,如果你这样做了,那么第二个仍然是可取的,因为它在逻辑上更简洁明了 函数good()应在尝试读取

以及:

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

while (std::getline(fs, line))
{}
这不仅是正确的,而且更可取,因为它是惯用的。

我假设在第一种情况下,如果(!fs)中断,则在
std::getline()
as
之后没有检查
fs
或类似的东西。因为如果你不这样做,那么第一个案例是完全错误的。或者,如果你这样做了,那么第二个仍然是可取的,因为它在逻辑上更简洁明了

函数
good()
应在尝试读取流后使用;它用于检查尝试是否成功。在第一种情况下,您不会这样做。在
std::getline()
之后,假设读取成功,甚至没有检查
fs.good()
返回的内容。另外,您似乎假设如果
fs.good()
返回true,
std::getline
将成功地从流中读取一行。实际上,如果
std::getline
成功地从流中读取一行,那么
fs.good()
将返回
true

cplusplus的文档中提到了这一点

如果未设置流的任何错误标志(eofbit、failbit和badbit),则函数返回true

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

如果要将
变量的范围仅限于循环内部,则可以为
循环编写
,如下所示:

for(std::string line; std::getline(fs, line); )
{
   //use 'line'
}
注意:在阅读了@john的解决方案后,我想到了这个解决方案,但我认为它比他的版本好


请阅读此处的详细说明,说明为什么第二个选项更可取且更惯用:

或者读一下@Jerry Coffin写得很好的博客:

试试这个=>

// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () {
  string line;
  ifstream myfile ("example.txt");
  if (myfile.is_open())
  {
    while ( myfile.good() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }

  else cout << "Unable to open file"; 

  return 0;
}
//读取文本文件
#包括
#包括
#包括
使用名称空间std;
int main(){
弦线;
ifstream myfile(“example.txt”);
如果(myfile.is_open())
{
while(myfile.good())
{
getline(myfile,line);

cout第一个循环每次释放并重新分配字符串,浪费时间。

第二次将字符串写入已存在的空间,删除释放和重新分配,使其实际上比第一次更快(更好)。

实际上,我更喜欢另一种方式

for (;;)
{
  std::string line;
  if (!getline(myFile, line))
    break;
  ...
}
对我来说,它读起来更好,而且字符串的作用域正确(即,在使用它的循环内,而不是在循环外)


但是,在你写的两篇文章中,第二篇是正确的。

把这看作是对纳瓦兹已经很好的答案的延伸评论

关于你的第一个选择

while (fs.good()) {
  std::string line;
  std::getline(fs, line);
  ...
这有多个问题。问题1是
while
条件位于错误的位置并且是多余的。它位于错误的位置,因为
fs.good()
表示最近对文件执行的操作是否正常。while条件应与即将进行的操作有关,而不是与以前的操作有关。无法知道对文件执行的即将进行的操作是否正常。什么即将进行的操作?
fs.good()
不读取代码以查看即将执行的操作

第二个问题是,您忽略了来自
std::getline()
的返回状态。如果您立即使用
fs.good()
检查状态,这没关系。因此,请稍微解决一下

while (true) {
  std::string line;
  if (std::getline(fs, line)) {
    ...
  }
  else {
     break;
  }
}

可选地,如果(.STD::GETLINE(FS,LINE))中断,},但现在在循环的中间有一个<代码>中断/代码>,那么,如果可能的话,最好让退出条件成为循环语句本身的一部分。 与之相比

std::string line;
while (std::getline(fs, line)) {
  ...
}
这是从文件中读取行的标准习惯用法。C中也有一个非常类似的习惯用法。这个习惯用法非常古老,使用非常广泛,被广泛认为是从文件中读取行的正确方法

如果你来自一个禁止附带条件的商店?(有很多很多的编程标准都是这样做的)有一个方法可以绕过中间循环的中断:

std::string line;
for (std::getline(fs, line); fs.good(); std::getline(fs, line)) {
  ...
}
不像break方法那么难看,但大多数人都会同意,这并不像标准的习惯用法那么好看

我的建议是使用标准成语,除非某些标准禁止使用

附录
关于(std::getline(fs,line);fs.good();std::getline(fs,line))的
:这很难看,有两个原因。一个是明显的复制代码块


<> P> >调用< <代码> GETLION>代码>然后>代码> Gue< /Calp>打破原子性。如果其他线程也从文件中读取,这又不是什么重要的事情,因为C++ I/O当前不是线程安全的。它将在即将到来的C++ 11中。ipe为灾难。

yikes,谷歌给我带来的最大打击是:方法名good()是如何成为标准的?:@jda:函数
good()
应该在您尝试读取流后使用;它用于检查尝试是否成功。在您的第一个例子中,您不会这样做。在
std::getline()之后
,您假设读取成功,甚至没有检查
fs.good()
返回的内容。此外,您似乎假设如果
fs.good()
返回true,
std::getline
std::string line;
for (std::getline(fs, line); fs.good(); std::getline(fs, line)) {
  ...
}