c++ - 使用 copy+back_inserter 将文件流式传输到 vector<float>

标签 c++ vector stream ifstream

我需要从文件中读取 float 并将它们插入我的 vector 中。我可以通过使用临时 float 让他工作,但我现在正在尝试不使用临时 float 。

出于某种原因,以下内容不起作用。

std::ifstream fileHandle(filename);
std::vector<float> vect;
std::string id;
while (!fileHandle.eof()){
    fileHandle >> id;
    std::copy(std::istream_iterator<float>(fileHandle),
              std::istream_iterator<float>(),
              std::back_inserter(vect));
    std::copy(std::istream_iterator<float>(fileHandle),
              std::istream_iterator<float>(),
              std::back_inserter(vect));
    std::copy(std::istream_iterator<float>(fileHandle),
              std::istream_iterator<float>(),
              std::back_inserter(vect));
}

文件看起来像

v 0.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
...

调试它,似乎第一个 copy 调用将 3 float (整行)插入 vector 。这实际上很好,除了它似乎也将我的文件迭代器卡住在下一行的“v”处。 fileHandle >> id; 行和 copy 调用不会从该点向前移动文件迭代器,从而创建一个无限循环。仅使用 1 个 copy 调用创建相同的结果。

我做错了什么?

最佳答案

#include<iostream>
#include<fstream>
#include<iterator>
#include<vector>

// it is a good idea to create an structure to hold the data you will
// be working with. In this case I am creating a bare-bones struct
// containing a single data element
struct entry {
  double data[3];  
};

// when you have an structure, you can overload the >> operator; this
// will allow you to simplify later calls (as you will see below). In
// this case, because your data file contains a "dummy" character I
// use a dummy string. Notice that the return type is bool, and it
// means "I was able to read what you wanted me to read", in this case
// a line with one string and three doubles (because the type of each
// e.data[k] is "double")
bool operator>>(std::istream& is, entry& e) {
  std::string dummy;
  return is>>dummy>>e.data[0]>>e.data[1]>>e.data[2];
}


int main() {
  // create a vector to hold the entries (notice that "entry" is the
  // data type you created above)
  std::vector<entry> entries;

  { // the bracket on the left will provide a "scope" for the "fp"
    // variable. When the scope ends, "fp" will be automatically
    // destroyed. For "fp" that means that the "close()" method will
    // be called upon destruction, and you don't need to worry about
    // ensuring that your files are closed (to lear more about this
    // google for RAII)

    std::ifstream fp("test.txt");
    // the iterators DO NOT REQUIRE A LOOP (they "provide" the loop;
    // they are used precisely to avoid coding the loop)

    std::copy(std::istream_iterator<entry>(fp),
              std::istream_iterator<entry>(),
              std::back_inserter<std::vector<entry>>(entries));
    // notice that the back inserter will insert "entry" types into
    // the "entries" vector as long as it can continue reading them
    // (that is, as long as ">>" continues to return "true"

  } // the bracket on the left is finishing the scope I talked about
    // above. Past this point fp no longer exists, and the file has
    // been closed

  // off you go - you have your vector full of "entry" instances which
  // you can use normally
  std::cout<<"read "<<entries.size()<<" entries: "<<std::endl;
  for(auto e:entries) {
    std::cout<<e.data[0]<<", "<<e.data[1]<<", "<<e.data[2]<<std::endl;
  }

  return 0;
}

我使用 gcc 4.7.2 编译了这个源代码:

g++ example.cpp -std=c++11

使用完全按照您提供的文件(我称之为“test.txt”),我得到以下信息:

read 2 entries: 
0, 0, 1
1, 0, 1

关于c++ - 使用 copy+back_inserter 将文件流式传输到 vector<float>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16488630/

相关文章:

c++ - 为什么 "inline"与 "virtual"不兼容

c++ - 包含指向多态类的指针的 vector

Ruby 压缩流

c# - DotNetZip 失败并显示 "stream does not support seek operations"

json - 打印缺少键的空字符串并将结果转换为 CSV

c++ - 命名空间、 header 和对象的层次结构

c++ - 使用RDBMS来减少内存消耗?

c++ - C++ 中类似 C# 的事件,组合

swift:将 y 轴定向到 3-d 空间中的另一个点

c++ - 如何在 C++ 中反转字符串 vector ?