我喜欢在python中我可以做的事情:
points = [] for line in open("data.txt"): a,b,c = map(float, line.split(',')) points += [(a,b,c)]
基本上它正在读取行列表,其中每行代表3D空间中的一个点,该点表示为由逗号分隔的三个数字
如何在没有太多头痛的情况下在C++中完成这项工作?
性能不是很重要,这种解析只发生一次,因此简单性更重要.
PS我知道这听起来像是一个新手问题,但相信我,我在D中编写了一个词法分析器(非常类似于C++),它涉及通过char读取一些文本char并识别标记,
就是这样,经过很长时间回到C++蟒蛇时期,只是让我不想浪费时间在这些事情上.
我会做这样的事情:
ifstream f("data.txt"); string str; while (getline(f, str)) { Point p; sscanf(str.c_str(), "%f, %f, %f\n", &p.x, &p.y, &p.z); points.push_back(p); }
x,y,z必须是浮点数.
并包括:
#include#include
在C++字符串工具箱库(StrTk)具有以下问题的解决方案:
#include#include #include "strtk.hpp" struct point { double x,y,z; } int main() { std::deque points; point p; strtk::for_each_line("data.txt", [&points,&p](const std::string& str) { strtk::parse(str,",",p.x,p.y,p.z); points.push_back(p); }); return 0; }
更多例子可以在这里找到
除了所有这些好的例子,在C++中你通常会覆盖operator >>
你的点类型来实现这样的事情:
point p; while (file >> p) points.push_back(p);
甚至:
copy( istream_iterator(file), istream_iterator (), back_inserter(points) );
运算符的相关实现看起来非常像j_random_hacker的代码.
#include#include #include #include #include #include // For replace() using namespace std; struct Point { double a, b, c; }; int main(int argc, char **argv) { vector points; ifstream f("data.txt"); string str; while (getline(f, str)) { replace(str.begin(), str.end(), ',', ' '); istringstream iss(str); Point p; iss >> p.a >> p.b >> p.c; points.push_back(p); } // Do something with points... return 0; }
这个答案是基于j_random_hacker之前的回答,并使用了Boost Spirit.
#include#include #include #include #include using namespace std; using namespace boost; using namespace boost::spirit; struct Point { double a, b, c; }; int main(int argc, char **argv) { vector points; ifstream f("data.txt"); string str; Point p; rule<> point_p = double_p[assign_a(p.a)] >> ',' >> double_p[assign_a(p.b)] >> ',' >> double_p[assign_a(p.c)] ; while (getline(f, str)) { parse( str, point_p, space_p ); points.push_back(p); } // Do something with points... return 0; }