当前位置:  开发笔记 > 编程语言 > 正文

C++字符串解析(python样式)

如何解决《C++字符串解析(python样式)》经验,为你挑选了5个好方法。

我喜欢在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++蟒蛇时期,只是让我不想浪费时间在这些事情上.



1> klew..:

我会做这样的事情:

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 


如果您决定从使用浮动更改为使用双打,请不要忘记将每个%f更改为%lf.在这种情况下,不需要更改使用operator >>()而不是sscanf()的解决方案.

2> 小智..:

在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;
}

更多例子可以在这里找到



3> Konrad Rudol..:

除了所有这些好的例子,在C++中你通常会覆盖operator >>你的点类型来实现这样的事情:

point p;
while (file >> p)
    points.push_back(p);

甚至:

copy(
    istream_iterator(file),
    istream_iterator(),
    back_inserter(points)
);

运算符的相关实现看起来非常像j_random_hacker的代码.



4> j_random_hac..:
#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;
}



5> Benoît..:

这个答案是基于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;
}


也许是因为使用boost :: spirit来解析逗号分隔列表是一种矫枉过正?Boost :: spirit会显着影响编译时间.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有