【问题标题】:copy algorithm with ifstream使用 ifstream 复制算法
【发布时间】:2012-03-30 22:46:32
【问题描述】:

以下代码的行为与我预期的不同。请帮助我了解它是如何工作的。

#include <algorithm>
#include <iterator>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

struct user
{
        string name;
        string age;
        string id;
};

istream& operator>>(istream& is, user& s)
{
        getline(is, s.name, ':');
        getline(is, s.age, ':');
        getline(is, s.id);

        return is;
}

int main(int argc, char* argv[])
{
        ifstream file("file.txt");
        vector<user> vec;
        copy(istream_iterator<user>(file), istream_iterator<user>(), back_inserter(vec));

        return 0;
}

我的自定义操作符>>被调用了两次,但我希望它只被调用一次,因为内容是:

约翰:四十:21-5821-0

【问题讨论】:

  • 你怎么知道它被调用了两次?检查调试器?你在向量中有两个条目?如果是最后一个,两个条目是否相同?
  • +1,最近遇到了同样的问题……由于某种原因,copy 代码中的迭代器增量导致了读取,而不是取消引用,因此它执行了一次读取太多。也就是说,您的operator &gt;&gt; 需要检查前两次getline 操作后的状态!
  • 担心不检查返回值的 I/O 代码是没有意义的。您必须始终检查 I/O 操作的返回值。
  • 这对我来说似乎很奇怪。 vec 的大小为 1,但 operator>> 被调用了两次。感谢 cmets。
  • @kisplit:第二次调用它是为了让它知道它到达了文件的末尾。它怎么知道它读取了整个文件,除非它读取直到读取失败?第二次失败,所以它知道没有更多数据了。

标签: c++ iterator ifstream stl-algorithm istream-iterator


【解决方案1】:

一般来说,要读入整个文件,您会一直读到读失败。然后你知道要么出了问题,要么你得到了所有。无论哪种方式,在您无法阅读之前,您都不知道您已到达文件末尾。既然第一个成功了,就必须再试第二次,看看是否还有第二个元素。这个伪代码是

while(in_stream >> object) {
   myvector.push_back(object);
}

另请注意,这是读取整个值文件的“惯用”方式。如果您正在检查eoffailbad,那么您的代码可能是错误的。

也就是说,您的istream&amp; operator&gt;&gt;(istream&amp; is, user&amp; s) 功能很好。第二次调用时,第一个getline 将失败,将流设置为错误状态(eof),接下来的两个getlines 也将失败,它将返回流,一切正常。请记住,这些变量中的任何一个或所有变量都可能完全是一派胡言,因为读取失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2021-11-23
    • 2017-06-28
    • 2021-07-25
    相关资源
    最近更新 更多