복붙노트

[PYTHON] C ++ 문자열 파싱 (파이썬 스타일)

PYTHON

C ++ 문자열 파싱 (파이썬 스타일)

나는 파이썬에서 어떻게하면 좋을지 좋아한다.

points = []
for line in open("data.txt"):
    a,b,c = map(float, line.split(','))
    points += [(a,b,c)]

기본적으로 각 라인이 3D 공간에서 포인트를 나타내는 라인 목록을 읽습니다. 포인트는 쉼표로 구분 된 세 개의 숫자로 표시됩니다.

너무 두통없이 C ++에서 어떻게이 작업을 수행 할 수 있습니까?

성능은 그다지 중요하지 않으며,이 구문 분석은 한 번만 발생하므로 단순성이 더 중요합니다.

추신 나는 초보자 질문처럼 들리지만, D (거의 C ++과 비슷한)에 렉서 (lexer)를 작성했다고 생각한다. 렉서는 숯으로 텍스트를 읽고 토큰을 인식하고, 파이썬의 오랜 기간이 지난 후에 C ++로 되돌아 오는 것입니다. 단지 그런 일에 시간을 낭비하고 싶지 않습니다.

해결법

  1. ==============================

    1.나는 이렇게 할 것이다.

    나는 이렇게 할 것이다.

    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는 반드시 float이어야합니다.

    포함 :

    #include <iostream>
    #include <fstream>
    
  2. ==============================

    2.C ++ String Toolkit Library (StrTk)에는 다음과 같은 문제에 대한 해결책이 있습니다.

    C ++ String Toolkit Library (StrTk)에는 다음과 같은 문제에 대한 해결책이 있습니다.

    #include <string>
    #include <deque>
    #include "strtk.hpp"
    
    struct point { double x,y,z; }
    
    int main()
    {
       std::deque<point> 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. ==============================

    3.이러한 좋은 예를 제외하고 C ++에서는 일반적으로 다음과 같이하기 위해 점 유형에 대해 연산자 >>를 재정의합니다.

    이러한 좋은 예를 제외하고 C ++에서는 일반적으로 다음과 같이하기 위해 점 유형에 대해 연산자 >>를 재정의합니다.

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

    또는:

    copy(
        istream_iterator<point>(file),
        istream_iterator<point>(),
        back_inserter(points)
    );
    

    연산자의 관련 구현은 j_random_hacker에 의한 코드와 매우 비슷하게 보일 수 있습니다.

  4. ==============================

    4.

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <algorithm>     // For replace()
    
    using namespace std;
    
    struct Point {
        double a, b, c;
    };
    
    int main(int argc, char **argv) {
        vector<Point> 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. ==============================

    5.이 답변은 j_random_hacker의 이전 답변을 기반으로하며 Boost Spirit을 사용합니다.

    이 답변은 j_random_hacker의 이전 답변을 기반으로하며 Boost Spirit을 사용합니다.

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <boost/spirit.hpp>
    
    using namespace std;
    using namespace boost;
    using namespace boost::spirit;
    
    struct Point {
        double a, b, c;
    };
    
    int main(int argc, char **argv) 
    {
        vector<Point> 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;
    }
    
  6. ==============================

    6.Boost.Tuples로 재미 :

    Boost.Tuples로 재미 :

    #include <boost/tuple/tuple_io.hpp>
    #include <vector>
    #include <fstream>
    #include <iostream>
    #include <algorithm>
    
    int main() {
        using namespace boost::tuples;
        typedef boost::tuple<float,float,float> PointT;
    
        std::ifstream f("input.txt");
        f >> set_open(' ') >> set_close(' ') >> set_delimiter(',');
    
        std::vector<PointT> v;
    
        std::copy(std::istream_iterator<PointT>(f), std::istream_iterator<PointT>(),
                 std::back_inserter(v)
        );
    
        std::copy(v.begin(), v.end(), 
                  std::ostream_iterator<PointT>(std::cout)
        );
        return 0;
    }
    

    튜플이 별도의 줄에있을 필요가 없기 때문에 이것은 질문의 파이썬 코드와 정확히 동일하지 않습니다. 예를 들면 다음과 같습니다.

    1,2,3 4,5,6
    

    다음과 같은 출력을 제공합니다.

    1,2,3
    4,5,6
    

    그것이 버그인지 기능인지 결정하는 것은 당신에게 달려 있습니다. :)

  7. ==============================

    7.std :: iostream 파일을 한 줄씩 읽어 들일 수 있으며 각 줄을 std :: string에 넣은 다음 boost :: tokenizer를 사용하여 파일을 분할 할 수 있습니다. 그것은 꽤 우아하고 / 파이썬 하나 짧지 만 한 번에 한 캐릭터에서 물건을 읽는 것보다 훨씬 쉽지 않을 것입니다 ...

    std :: iostream 파일을 한 줄씩 읽어 들일 수 있으며 각 줄을 std :: string에 넣은 다음 boost :: tokenizer를 사용하여 파일을 분할 할 수 있습니다. 그것은 꽤 우아하고 / 파이썬 하나 짧지 만 한 번에 한 캐릭터에서 물건을 읽는 것보다 훨씬 쉽지 않을 것입니다 ...

  8. ==============================

    8.그것의 아무데도 간결한, 그리고 물론 나는 이것을 컴파일하지 않았다.

    그것의 아무데도 간결한, 그리고 물론 나는 이것을 컴파일하지 않았다.

    float atof_s( std::string & s ) { return atoi( s.c_str() ); }
    { 
    ifstream f("data.txt")
    string str;
    vector<vector<float>> data;
    while( getline( f, str ) ) {
      vector<float> v;
      boost::algorithm::split_iterator<string::iterator> e;
      std::transform( 
         boost::algorithm::make_split_iterator( str, token_finder( is_any_of( "," ) ) ),
         e, v.begin(), atof_s );
      v.resize(3); // only grab the first 3
      data.push_back(v);
    }
    
  9. ==============================

    9.Sony Picture Imagework의 오픈 소스 프로젝트 중 하나는 Pystring입니다. Pystring은 문자열 분할 파트의 대부분을 직접 번역해야합니다.

    Sony Picture Imagework의 오픈 소스 프로젝트 중 하나는 Pystring입니다. Pystring은 문자열 분할 파트의 대부분을 직접 번역해야합니다.

    몇 가지 예제와 몇 가지 문서가 있습니다.

  10. ==============================

    10.이 모든 것이 좋은 예입니다. 아직 그들은 다음과 같은 대답을하지 않는다 :

    이 모든 것이 좋은 예입니다. 아직 그들은 다음과 같은 대답을하지 않는다 :

    그래서 아직도 찾고있는 사람들을 위해,이 수업 : http://www.codeguru.com/cpp/tic/tic0226.shtml 꽤 멋지다. 약간의 변화가 필요할지도 모른다.

  11. from https://stackoverflow.com/questions/536148/c-string-parsing-python-style by cc-by-sa and MIT license