Синтаксический анализ строки 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 довольно круто … могут потребоваться некоторые изменения

  • Вызовите C ++ opencv-функции из Python (отправьте cv :: Mat в C ++ dll, использующую opencv)
  • Как создать карту типа OUTPUT для типа класса?
  • Использование сеанса SQLAlchemy из Flask повышает «объекты SQLite, созданные в потоке, могут использоваться только в том же потоке»
  • Есть ли эквивалент Python для C ++ «multiset <int>»?
  • Возвращаемое значение вызова функции system () в C ++, используемое для запуска программы Python
  • C ++ имя mangling вручную
  • Дизайн виртуальной пробной комнаты
  • Как скомпилировать OpenGL с расширением C ++ python с использованием distutils на Mac OSX?
  • двойное преобразование PyFloat неверно
  • .so не импортирует в python: динамический модуль не определяет функцию init
  • Плохая Linux-память, сопоставленная производительностью файлов с произвольным доступом C ++ и Python
  •  
    Interesting Posts for Van-Lav

    Каков самый быстрый способ слияния двух списков в python?

    Согласование вложенных структур с регулярными выражениями в Python

    Python PyQt4 функции для сохранения и восстановления значений виджета пользовательского интерфейса?

    Обработка нестандартных американских английских символов и символов в CSV с использованием Python

    Как перенаправить вывод регистратора в текстовый виджет PyQt

    Самый простой способ rm -rf в Python

    Преобразование HTML в CSV

    Соединение UniqueConstraint с функцией

    Как изменить имя приложения в строке меню OSX в наборе приложений с чистым Python?

    Как полезен интроспекция?

    Ошибка Django 1.4.1 при загрузке модуля MySQLdb при попытке «python manage.py shell»

    Ошибка «Разрешить отказ» разрушает Selenium scraping

    Pythonic способ установить полный столбец для значения Pandas (SettingWithCopyWarning)

    Как установить одинаковый цвет для маркеров и линий в цикле графика matplotlib?

    Rapsberry BLE периферийные устройства, альтернативные bleno

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