用C ++打开文件 - getline在第二次迭代时失败

时间:2013-01-28 08:36:23

标签: c++ xcode file-io

我无法弄清楚为什么getline在一个X-Code项目中工作而在另一个X-Code项目中不工作。错误“没有匹配函数来调用'getline'。 当我制作单个cpp文件时,它编译没有问题。

  // 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;
}

我真的很感激一些帮助。我只是在学习,上面的例子来自我的测试书。

2 个答案:

答案 0 :(得分:5)

代码嘈杂且不正确。正确的标准习语是这样的:

#include <fstream>   // for std::ifstream
#include <string>    // for std::getline and std::string

std::ifstream myfile("example.txt");

if (!myfile) { /* error, die */ }

for (std::string line; std::getline(myfile, line); )
{
    std::cout << "Read one line: '" << line << "'\n";
}

<强>正确性:

  • 您必须在消费输入之前检查输入操作是否成功。否则可能是UB,当然永远不会纠正。

  • [感谢@James指出这一点:] good()不会检查文件是否已打开。您可以使用!myfile.fail()myfile.is_open(),但不要打扰(见下文)。

<强>噪声:

  • ifstream构造函数接受文件名并打开文件。使用它。

  • ifstream在析构函数中清理,不需要明确地执行此操作。一旦完成,请使用紧密的范围来关闭文件。

  • 如果您不需要,请不要将line泄漏到环境范围内。

  • 不需要good()(或任何正确的替代方案)。只需在布尔上下文中评估ifstream对象,看看文件是否已成功打开。

答案 1 :(得分:1)

有一个实际错误:您使用getline的结果 没有测试它是否成功。通常的方式 写你的内循环将是:

std::string line;
while ( std::getline( myfile, line ) ) {
    std::cout << line << std::endl;
}

其他人更多的是风格问题,尽管有些问题可以解决 享受几乎普遍的共识:不要定义变量 在你需要它之​​前,例如(因此,定义 line应该紧接在循环之前)。错误输出 转到std::cerr,而不是std::out. And in case of an error, you should return EXIT_FAILURE , and not 0`。

人们普遍认为,您没有明确要求 关闭输入(因为析构函数会处理它,并且 你已经成功阅读了所有内容)。共识 对于其他人来说并不完整:例如,我绝不会使用using namespace std;,而且我永远不会将代码放在后面 else在同一行。我还发现代码更具可读性 if...else中的较短条件是第一个,所以我写道:

if ( !myfile.is_open() ) {
    std::cout << "Unable to open file" << std::endl
    returnCode = EXIT_FAILURE;
} else {
    std::string line;
    while ( std::getline( myfile, line ) ) {
        std::cout << line << std::endl;
    }
    returnCode = EXIT_SUCCESS;
}

除了对于任何更复杂的事情,我会考虑因素 将文件处理成单独的函数。所以我结束了 类似的事情:

if ( myfile.is_open() ) {
    process( myfile );
} else {
    //  error handling...
}

但你似乎暗示你遇到了问题 您未发布的代码中的std::getline。有两个显而易见的 可能的说明:你没有包括<string>,或者你 忘记了前面的std::。还有其他可能 explinations,但我们必须实际看到代码 没有说出确切的错误。