<float> 使用 copy+ 将文件流式传输到矢量back_inserter
stream a file to a vector<float> with copy+back_inserter
我需要从文件中读取浮点数并将它们放入向量中。我可以让他的工作通过使用一个临时浮动,但我现在正在尝试没有一个。
由于某些原因,下面的代码不能工作。
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浮点数(整行)推入向量。这实际上是好的,除了它似乎也冻结了我的文件迭代器在下一行的'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
这里有一个使用Boost Spirit的简单方法。
这为您提供了难以置信的灵活性,因为它定义了一个实际的内联语法:
('v' >> qi::float_ >> qi::float_ >> qi::float_) % qi::eol,
完整的程序如下:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi = boost::spirit::qi;
int main()
{
std::cin >> std::noskipws;
boost::spirit::istream_iterator f(std::cin), l;
std::vector<float> vect;
bool ok = qi::phrase_parse(f,l, // std::cin
('v' >> qi::float_ >> qi::float_ >> qi::float_) % qi::eol,
qi::blank, // ignore any whitespace separators
vect); // keep appending to a vector
// (this could easily be a vector of structs containing 3 floats)
if (ok)
{
std::cout << "parse successn";
// only for verification output:
using namespace boost::spirit::karma;
std::cout << "parsed vect: n" << format_delimited(columns(3) [ *auto_ ], ' ', vect) << "n";
}
else std::cerr << "parse failed: '" << std::string(f,l) << "'n";
if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'n";
return ok;
}
相关文章:
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- Angelscript从C++传输数组
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 从服务器传输到客户端的消息不会出现
- USB传输的LibUSB C++格式不同
- 推导 std::vector::back() 的返回类型
- 在本地网络中通过OpenCV(C++)实时流式传输图像
- 将相机数据从服务器实时流式传输到客户端
- 加密在 Windows、C++ 和 Java 中传输中的数据
- 如何从网站获取数据并将其传输到数据库?
- vector.back() 和 vector[vector.size() - 1] 之间的区别?
- 使用蓝牙组件将数据从Android手机传输到串行设备时出现问题
- 在 OpenCV 中应用公式并传输图像
- 在不传输的情况下更改 Win32 中的串行端口波特率
- Vulkan 的传输队列系列功能和显卡支持:条件检查是否准确?
- 如何使用CAPL的诊断功能获取CAN传输的数据(256字节)?
- 如何通过ROS将realsense数据传输到其他设备
- 将音频从浏览器流式传输到WebRTC本机C++应用程序
- 将FFMpeg AVFrame对象从C++应用程序流式传输到Python的最佳方法?
- 使用IMFSourceReader(Microsoft媒体基金会)进行音频流传输