【问题标题】:Getline in c++ ifstream causing unwanted behavoir?c ++ ifstream中的Getline导致不需要的行为?
【发布时间】:2012-04-01 11:51:03
【问题描述】:

我认为我的 getline 函数有问题,给我一个与字符有关的错误。

我得到的错误是:

错误 1 ​​错误 LNK2019:未解析的外部符号 "public: void __thiscall ArrayStorage::read(class std::basic_ifstream<char,struct std::char_traits<char> > &)" (?read@ArrayStorage@@QAEXAAV?$basic_ifstream@DU?$char_traits@D@std@@@std@@@Z) 在函数 _main C:\用户\Lewis\SVN\project1\main.obj

任何想法都将不胜感激。如果有人使用这种类型的数组有更有效的方法来完成这项任务,我会接受任何给出的建议。

【问题讨论】:

  • 这是一个链接器错误,而不是编译器错误。无论如何,你的行阅读习语是错误的(你不能使用 EOF),但是关于 SO 处理的问题确实有一百万个问题。
  • !fin.eof() 不保证getline 会成功。 (虽然这肯定不是链接器错误的原因。)
  • 是什么让您认为getline 与此问题有任何关系?它以前是否有效,但只有在添加那一行后才开始失败?我的猜测是您不了解getline 的工作原理,并且由于您遇到了问题,因此您立即将注意力集中在“外国”功能上作为替罪羊,而不是仔细阅读错误消息以查看它真正在抱怨什么.

标签: c++ arrays getline


【解决方案1】:

blah blah blah 未解析的外部符号 "public: void __thiscall ArrayStorage::read (class std::basic_ifstream<char,struct std::char_traits<char> > &)" blah blah blah

这是一个链接器错误。这意味着缺少函数ArrayStorage::read 的定义。为什么?因为代码中有一个名为read 的函数的定义,而不是ArrayStorage::read。如果你定义ArrayStorage::read,它应该会找到它:

//Array cpp:
void ArrayStorage::read(ifstream& fin)
// ...

一旦你克服了这个问题,程序可能就可以运行了。而且您可能会因为读取循环而发现错误。 while (! fin.eof() ) 不会“在文件不在末尾时[运行]”。它在之前的读取操作没有尝试读取结束时运行。考虑在进行检查时必须已经发生的事情:

while (! fin.eof() ) // in the last iteration the read didn't go beyond the end of the file
{                    // so one more iteration is ran
    getline (fin,line); // tries to read past the end, fails

    if (line == "") continue; // line is unchanged, so it could be a non-blank line from before

    myArray[arrayIndex]=line; // Saves that line in the array:
                              // even though no line was read
    arrayIndex++;
} // goes back to the start of the loop, and only now !fin.eof() fails
  // but it's too late, the damage has been done

您可能不希望这种情况发生。您想在阅读失败后立即停止阅读。这很简单:只需将读数作为条件:

while (getline (fin,line)) // if reading a line fails, the loop is not entered
{                          // and so no extra line is added to the array

【讨论】:

  • 非常感谢您的详细回复。出于某种原因,虽然它不会到达字符串列表的末尾,但它会在中途停止,是否有任何可能的原因(我已经将我的代码更新为你给我的)再次感谢。
【解决方案2】:

如果我记得,这个链接器错误有时可能是由于您的类或其基础之一具有未定义的 other 虚函数。错误发生在命名的函数上,而不是实际缺少定义的虚函数上,因为 MSVC 编译器会一直等待,直到找到第一个具有已定义虚函数的 CPP 文件,以便类将类头定义函数的定义粘贴在,并且当它没有找到这样的 CPP 文件时,它永远不会定义类头定义的函数。 GCC 在这方面的行为与 MSVC 不同;我相信 GCC 会在它们使用的每个目标文件中保留定义,并在链接时丢弃额外内容。 MSVC 仅定义一次,因此可能会意外地从未定义它。它不能“只知道”它“忘记”插入定义的原因是因为编译器可以随时增量调用,一次只能在一些文件上调用,所以它没有全局.

【讨论】:

    【解决方案3】:

    您没有提供Array::read() 函数的定义。您正在声明一个名为 read() 但与 Array 类无关的新函数。编译器和链接器并不关心它是否在一个名为 Array.cpp 的文件中。

    试试这个:

    void Array::read(ifstream& fin)
    {
        //...
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-08
      • 1970-01-01
      • 2014-11-03
      • 2011-03-31
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多