Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66

Текстовый файл, в котором значения разделены точкой с запятой. Нужен ли regex?

30.01.2013, 17:39. Показов 3023. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет)

В общем, вопрос в том, как сделать правильнее и "красивее", что ли, такое вот задание.

Есть файлик, в котором заданное кол-во значений разделено точкой с запятой.
По типу:
value1;value2;value3;value4;value5; (et cetera)

Мне нравится вариант с регексом.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{ 
ifstream inpf ("C:\\datafile.txt", std::ios_base::in);
if (!inpf) cout << "datafile is missing";
else cout << "processing ...\n\n";
string data;                
boost::regex reg("(\\d{15});(\\d{16});(.*?);(.*?);(.*?);");         
boost::smatch m;
   while (std::getline (inpf, data)) {                      
    if (boost::regex_search(data, m, reg ))                 
            {
                cout << m[2] << "     " << m[5] << endl;
            }   
                else 
                cout << endl;
        }
inpf.close();
Все бы ок, но прикол в том, что значений этих 35, а мне нужны, грубо говоря, только 3е и 19е
Ну не писать же такое вот выражение:

C++
1
boost::regex reg("(\\d{15});(\\d{16});(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);");(.*?);(.*?);(.*?);(.*?);
Можно, конечно, через потоки, по типу:

C++
1
2
3
4
std::string str;
std::istringstream ss(str);
std::string value1;
ss >> value1;
Но тут прикол в том, что между двумя точками с запятой может быть и строка, разделенная пробелами:
";вот такая длинная строка с пробелами;".

В общем, как правильней, или, точнее, грамотней было бы это сделать?

Добавлено через 8 минут
ЗЫ Выражение с регекспом можно и подсократить, конечно:

C++
1
boost::regex reg("(\\d{15});(\\d{16});(.*?);(\\3){30};");
(Не уверен только, как тогда обратиться к 19му subexpression'у и правильно ли я написал вот эту часть: ;(\\3){30};

Но все равно, чувствую, не нужен тут regex, можно сильно проще ))
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.01.2013, 17:39
Ответы с готовыми решениями:

Слова в тексте разделены точкой с запятой. Определить сколько слов, заканчиваются буквой а.
Здравствуйте, помогите пожалуйста со троками Как можно решить эту задачу? Дан набор слов, разделенных точкой с запятой ( ; ). Набор...

Как правильно считать матрицу из текстовый файла, если числа разделены запятой
Здравствуйте! Считываю матрицу из текстового файла следующим образом: m=importdata('in.txt'); X=m(1,2:end); Y=m(2:end,1); ...

Ввести предложение, слова в котором разделены пробелами и запятыми. После каждой запятой поставить пробел, если его там нет
Ввести предложение, слова в котором разделены пробелами и запятыми. После каждой запятой поставить пробел, если его там нет

15
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
30.01.2013, 17:42
Чем плох вариант с boost::split с семиколонной в качестве разделителя?
1
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66
30.01.2013, 17:43  [ТС]
Цитата Сообщение от diagon Посмотреть сообщение
Чем плох вариант с boost::split с семиколонной в качестве разделителя?
Ну видимо тем, что я про него не знал
Пасиб. Щас гляну.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.01.2013, 17:59
C++
1
while(std::getline(in, token, ';')) tokens.push_back(token);
потом к любому элементу через tokens[индекс] где tokens - вектор, in - ifstream, token - стринг
1
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
30.01.2013, 18:06
Excogit8er, может как-нибудь так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
 
#include <boost/regex.hpp>
 
 
int main() {
   std::string line;
   std::getline(std::cin, line);
   boost::regex regex("^(((.*?);)){2}(.*?);((.*?);){16}(.*?);");
   boost::smatch match;
   if (boost::regex_match(line, match, regex)) {
      std::cout << match[4] << std::endl;
      std::cout << match[6] << std::endl;
   }
}
http://liveworkspace.org/code/3B2Vcq

Добавлено через 1 минуту
Так то со split попроще будет, пожалуй)
0
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66
30.01.2013, 18:20  [ТС]
Цитата Сообщение от Vourhey Посмотреть сообщение
C++
1
while(std::getline(in, token, ';')) tokens.push_back(token);
потом к любому элементу через tokens[индекс] где tokens - вектор, in - ifstream, token - стринг
А при таком подходе строки не перепутаются? )
Так-то все ясно: while(std::getline(filename, str, '\n'))
И каждая строка потом парсится.
А так...

Добавлено через 2 минуты
Цитата Сообщение от gray_fox Посмотреть сообщение
Excogit8er, может как-нибудь так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
 
#include <boost/regex.hpp>
 
 
int main() {
   std::string line;
   std::getline(std::cin, line);
   boost::regex regex("^(((.*?);)){2}(.*?);((.*?);){16}(.*?);");
   boost::smatch match;
   if (boost::regex_match(line, match, regex)) {
      std::cout << match[4] << std::endl;
      std::cout << match[6] << std::endl;
   }
}
http://liveworkspace.org/code/3B2Vcq

Добавлено через 1 минуту
Так то со split попроще будет, пожалуй)
Ну, кстати, вариант. Со сплит я уже посмотрел примеры:

C++
1
2
3
4
5
6
7
8
9
   std::string s = "value1;value2;value number fucking 3;value4";
   s.erase(s.size() - 1);
   std::vector<std::string> v;
   boost::split(v, s, [](const char c) { return c == ';'; }, boost::token_compress_on);
   boost::copy(v | boost::adaptors::filtered([](const std::string& s)
   {
      return *s.begin() == *s.rbegin();
   }), std::ostream_iterator<std::string>(std::cout, "\n"));  
}
Жесть как она есть ) При этом пока не понял, как, скажем, вывести в консоль только (скажем) 3е и 19е subexpressions.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
30.01.2013, 18:32
Excogit8er, v[2], v[18]?

Добавлено через 2 минуты
Собственно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <vector>
 
#include <boost/algorithm/string.hpp>
 
 
int main() {
   std::string line;
   std::getline(std::cin, line);
   std::vector<std::string> tokens;
   boost::split(tokens, line, boost::is_any_of(";"), boost::token_compress_on);
   std::cout << tokens[2] << std::endl;
   std::cout << tokens[18] << std::endl;
}
http://liveworkspace.org/code/4zSbo8
0
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66
30.01.2013, 18:43  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
Excogit8er, v[2], v[18]?

Добавлено через 2 минуты
Собственно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <vector>
 
#include <boost/algorithm/string.hpp>
 
 
int main() {
   std::string line;
   std::getline(std::cin, line);
   std::vector<std::string> tokens;
   boost::split(tokens, line, boost::is_any_of(";"), boost::token_compress_on);
   std::cout << tokens[2] << std::endl;
   std::cout << tokens[18] << std::endl;
}
http://liveworkspace.org/code/4zSbo8
Ну это намного проще, спасибо ) Проверил только что:
C++
1
2
3
4
5
6
7
std::string s;
while (std::getline (inpf, s)) {    
std::vector<std::string> tokens;
boost::split(tokens, s, boost::is_any_of(";"), boost::token_compress_on);
std::cout << tokens[2] << std::endl;
std::cout << tokens[18] << std::endl;
}
Получил такое вот сообщение при компиляции:

"c:\program files\microsoft visual studio 10.0\vc\include\xutility(2227): warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1> c:\program files\microsoft visual studio 10.0\vc\include\xutility(2212) : see declaration of 'std::_Copy_impl'
1> c:\program files\boost\boost_1_51\boost\algorithm\s tring\detail\classification.hpp(102) : see reference to function template instantiation '_OutIt std::copy<const char*,char*>(_InIt,_InIt,_OutIt)' being compiled
1> with
1> [
1> _OutIt=char *,
1> _InIt=const char *
1> ]
1> c:\program files\boost\boost_1_51\boost\algorithm\s tring\classification.hpp(206) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<Ch arT>::is_any_ofF<boost::iterator_range<I teratorT>>(const RangeT &)' being compiled
1> with
1> [
1> CharT=char,
1> IteratorT=const char *,
1> RangeT=boost::iterator_range<const char *>
1> ]
1> c:\users\documents\visual studio 2010\projects\xml2roadnet\xml2roadnet\xm l2roadnet.cpp(91) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<Ch arT> boost::algorithm::is_any_of<const char[2]>(RangeT (&))' being compiled
1> with
1> [
1> CharT=char,
1> RangeT=const char [2]
1> ]"


А сама программка "валится" с ошибкой: "Expression: vector subscript out of range"
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.01.2013, 18:49
Цитата Сообщение от Excogit8er Посмотреть сообщение
А при таком подходе строки не перепутаются? )
Нечему и не с чего перепутываться
Цитата Сообщение от Excogit8er Посмотреть сообщение
А так...
А как? Хоть бы что понятное написал, а то одни междометия.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
30.01.2013, 18:55
Цитата Сообщение от Excogit8er Посмотреть сообщение
Получил такое вот сообщение при компиляции:
Студии не нравятся алгоритмы из std? )
Цитата Сообщение от Excogit8er Посмотреть сообщение
"Expression: vector subscript out of range"
Очевидно в строке не было 19 значений, соответственно и в tokens тоже.
0
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66
30.01.2013, 19:03  [ТС]
Цитата Сообщение от Vourhey Посмотреть сообщение
Нечему и не с чего перепутываться

А как? Хоть чтоб что понятное написал, а то одни междометия.
Я просто не понял, как строки различать при таком считывании?
Считать количество точек с запятой? А если в какой-то строке будет лишняя, скажем?

Ну, т.е.

C++
1
2
while(std::getline(in, token, ';')) tokens.push_back(token);
\\как понять, где конец строки?
Добавлено через 5 минут
Цитата Сообщение от gray_fox Посмотреть сообщение
Студии не нравятся алгоритмы из std? )
Ну, boost::split вроде бы не std ))
Но, блин, я VS только недавно начал пользоваться и уже понимаю, почему все плюются)

Очевидно в строке не было 19 значений, соответственно и в tokens тоже.
Не, вот кстати было - там их 38 (в каждой строке), или что-то около того. Но 19 точно есть.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
30.01.2013, 19:08
Цитата Сообщение от Excogit8er Посмотреть сообщение
Ну, boost::split вроде бы не std ))
Я про
warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe
Не, вот кстати было - там их 38 (в каждой строке), или что-то около того. Но 19 точно есть.
Ну как бы assertion говорит о выходе индекса за допустимые пределы. Может в конце пустую строку читаешь?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.01.2013, 19:16
Цитата Сообщение от Excogit8er Посмотреть сообщение
как строки различать при таком считывании?
"ifstream" это не обязательно файл, а лишь пример. Любой наследник istream'а может его заменить. Если у нас есть несколько строк в файле, то есть istringstream и тот же алгоритм.
Цитата Сообщение от Excogit8er Посмотреть сообщение
Считать количество точек с запятой? А если в какой-то строке будет лишняя, скажем?
Научись смотреть на вопрос в общем, а не упираться лбом в стенку.
0
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66
30.01.2013, 19:16  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
Я про
warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe
Да, не заметил) Похоже, что не нравятся...

Ну как бы assertion говорит о выходе индекса за допустимые пределы. Может в конце пустую строку читаешь?
Нет, я перенаправил вывод с консоли в файл - видно, что верно считывается 1я строкa (2 значения), а вот
на второй все заваливается. Но там пустые значения, т.е. просто две точки с запятой подряд.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
30.01.2013, 19:19
Цитата Сообщение от Excogit8er Посмотреть сообщение
1я строкa (2 значения)
Ну так считай все значения в одну строку сначала, потом разбирай )
0
2 / 2 / 1
Регистрация: 23.10.2012
Сообщений: 66
31.01.2013, 11:20  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
Ну так считай все значения в одну строку сначала, потом разбирай )
)) Все равно я не понял - если в массиве (vector<string>) строк одно из значений оказалось пустым, то это типа exception?

Спасибо всем. Завтра попробую оба варианта (поток и boost::split)


Добавлено через 15 часов 40 минут
Ну, в общем, как-то так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
std::string data;
while (std::getline (inpf, data)) {
std::istringstream sstr (data);
std::vector<std::string> tokens;
std::string token;
while(std::getline(sstr, token, ';')) 
tokens.push_back(token);            
for (int i = 0; i < tokens.size(); i++)
  { 
    if (i == 1)
                cout << tokens[i] << "---";
    if (i == 18)
        cout << tokens[i] << "---";  
  }
Причем, как мне показалось, так даже быстрее (скорость выполнения) чем через boost::split.

Vourhey
Ты был прав, все элементарно) Thanx
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.01.2013, 11:20
Помогаю со студенческими работами здесь

Дан многострочный текстовый файл слова разделены пробелами, сформировать новый файл с палиндромом строк первого файла
Подскажите что не так в создании и обработке второго файла... var i:integer;f,f1:text;S,s1:string; begin assign(f,'fff.txt');//...

Записать значение Double в файл не с запятой, а с точкой
Помогите пожалуйста(((((( При записи в файл числа, типа double, записываются с запятой, а нужно, чтоб записывались с точкой!!! Может...

Создать файл, в котором фамилии будут записаны в одну строку и разделены запятыми
Текстовый файл содержит несколько строк с фамилиями. Создать файл, в котором эти фамилии будут записаны в одну строку и разделены...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru