Синтаксический анализ строки C ++ (стиль python)

Мне нравится, как в питоне я могу сделать что-то вроде:

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

В основном это чтение списка строк, где каждый представляет точку в трехмерном пространстве, точка представляется в виде трех чисел, разделенных запятыми

Как это можно сделать на C ++ без слишком большой головной боли?

Производительность не очень важна, этот синтаксический анализ происходит только один раз, поэтому простота важнее.

PS Я знаю, что это звучит как вопрос новичков, но поверьте мне, я написал лексер в D (очень похожий на C ++), который включает в себя чтение некоторого текстового символа с помощью char и распознавание токенов,
это просто, вернувшись на C ++ после долгого периода python, просто заставляет меня не тратить время на такие вещи.

10 Solutions collect form web for “Синтаксический анализ строки C ++ (стиль python)”

Я бы сделал что-то вроде этого:

 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 <iostream> #include <fstream> 

Библиотека инструментов C ++ String Toolkit (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,",",px,py,pz); points.push_back(p); }); return 0; } 

Дополнительные примеры можно найти здесь

Все эти хорошие примеры, в C ++, вы обычно переопределяете operator >> для вашего точечного типа, чтобы добиться чего-то вроде этого:

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

или даже:

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

Соответствующая реализация оператора может очень похож на код j_random_hacker.

 #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 >> pa >> pb >> pc; points.push_back(p); } // Do something with points... return 0; } 

Этот ответ основан на предыдущем ответе 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(pa)] >> ',' >> double_p[assign_a(pb)] >> ',' >> double_p[assign_a(pc)] ; while (getline(f, str)) { parse( str, point_p, space_p ); points.push_back(p); } // Do something with points... return 0; } 

Развлечения с 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; } 

Обратите внимание, что это не является строго эквивалентным коду Python в вашем вопросе, потому что кортежи не обязательно должны быть в отдельных строках. Например, это:

 1,2,3 4,5,6 

даст тот же результат, что:

 1,2,3 4,5,6 

Это зависит от вас, чтобы решить, является ли это ошибкой или функцией 🙂

Вы можете прочитать файл из std :: iostream по строкам, поместить каждую строку в std :: string, а затем использовать boost :: tokenizer, чтобы разбить его. Это будет не так элегантно / коротко, как питон, но намного проще, чем читать вещи в персонаже за раз …

Его нигде не было столь кратким, и, конечно, я не скомпилировал это.

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

Одним из проектов с открытым исходным кодом Sony Picture Imagework является Pystring , который должен сделать главным образом прямой перевод разделов, разделяющих строки:

Pystring – это набор функций C ++, которые соответствуют интерфейсу и поведению методов класса строки python с помощью std :: string. Реализованный в C ++, он не требует или не использует интерпретатор python. Это обеспечивает удобство и знакомство с обычными строковыми операциями, не включенными в стандартную библиотеку C ++

Существует несколько примеров , и некоторые документы

все это хорошие примеры. но они не отвечают на следующее:

  1. CSV-файл с разными номерами столбцов (несколько строк с большим количеством столбцов, чем другие)
  2. или когда некоторые из значений имеют пробел (ya yb, x1 x2,, x2,)

поэтому для тех, кто все еще ищет, этот класс: http://www.codeguru.com/cpp/tic/tic0226.shtml довольно круто … могут потребоваться некоторые изменения

  • Boost.python vs Cython для интерфейса C ++ / python
  • Можно ли вызывать модуль Python из ObjC?
  • Зачем мне встраивать язык сценариев?
  • Соответствие строк: gcc и CPython
  • Общая библиотека SWIG и C ++
  • Эти функции python в c ++?
  • Связывание c ++ - класс для boost_python в cygwin
  • Метод Python для повышения функции
  •  
    Interesting Posts for Van-Lav

    Выбор значений из непустых столбцов в элементе данных PySpark DataFrame

    строка проверки python содержит все символы

    « Network недоступна» при попытке отправить электронную почту с помощью Django

    time.sleep требует целых чисел?

    из моделей импорта django.db, миграции ImportError: невозможно импортировать имена миграции

    Сценарий Python для зарядки и разрядки аккумулятора для ноутбука

    Использование OpenCV detectMultiScale для поиска моего лица

    Доступ к переменным из интерактивного пространства имен IPython в скрипте

    Разница между asfreq и resample

    Unicode для PHP exec

    Как выполнить итерацию по серии Pandas, сгенерированную из groupby (). Size ()

    Python разделяет строки и смешивает средние

    Как использовать диспетчер контекста, чтобы избежать использования __del__ в python?

    Запись и чтение сложных чисел с использованием numpy.savetxt и numpy.loadtxt

    Как получить локальный часовой пояс пользователя, кроме часового пояса сервера (UTC) в python?

    Python - лучший язык программирования в мире.