Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.67
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
#1

Парсинг адресной строки, хочу извлечь индекс и название города - C++

25.12.2012, 18:45. Просмотров 1888. Ответов 38
Метки нет (Все метки)

Всем доброго дня.

Хочу распарсить такой вот файлик:

------------------------------------------------------------
125414, Москва г, Петрозаводская ул, дом № 24а, корпус 2
125493, Москва г, Смольная ул, дом № 5
Москва г, Онежская ул, дом № 11.11.2008"
------------------------------------------------------------

Считать индекс в отдельный массив, потом название города в отдельный массив, скопировать их в общий массив символов и вывести в консоль. Нашел на сайте (cyberforum) пример, сделал по аналогии, чет ни фига не работает, гляньте, если не сложно:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
char zipcode[10] = { '0' };
char city[20] = { '0' };
char finalstring[30] = { '0' };
 
ifstream parsing_f ("parse_addresses.txt");
        while (!parsing_f.eof())
    {       
        parsing_f.getline(buff, 1024, '\n');
        
        char*  ptr_zip = buff;
            for (int zc = 0; zc < 10; zc++)
                zipcode[zc] = ' ';
        while ((ptr_zip = get_zipcode (zipcode, ptr_zip)))
        {
         for (int i = 0; i < 10; i++)
             finalstring[i] = zipcode[i]; }
            
        for (int ct = 0; ct < 20; ct++)
                city[ct] = ' ';
        const char * ptr_city = buff;
        while ((ptr_city = get_city(city, ptr_city, " г,")))
        {
         for (int i = 10; i < 30; i++)
             finalstring[i] = city[i]; }
                
        finalstring[30] = '\0';
        cout << finalstring << endl;
            
    }
        
    parsing_f.close();  
 
//функции получения адреса и индекса:
 
char*  get_zipcode(char* strzip, char* sourcestr) {
    
    char* ps = sourcestr;
    for (int i = 0; *ps && i < 6 &&  isdigit(*ps); i++)
    *strzip++ = *ps++;
 
    return ps;
}
 
const char*  get_city(char* strcity, const char* sourcestr, const char* searchstr) {
    const char* ps = strstr(sourcestr, searchstr);
    if(! ps)
        return NULL;
    while ((&sourcestr[0] != ps) && (*ps != ' '))
        ps--;
    while (*ps && *ps != ' ')
        *++strcity = *ps++;   
    return ps;
}
В функии, которая возвращает адрес символы, по которым осуществляется поиск, идут после названия города. Т.е. я сначала хочу "отмотать" указатель на название города, а потом уже считать его в массив символов. Поэтому и проверка: (&sourcestr[0] == ps) - чтобы не выйти за границы массива - город может начинаться с первого же символа в строке.

ЗЫ Только не советуйте boost и прочее, задачка вроде элементарная.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.12.2012, 18:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Парсинг адресной строки, хочу извлечь индекс и название города (C++):

Составить программу которая на введенную дату выдает название города - C++
Мы с вами знаем, что Санкт-Петербург менял свое название несколько раз. Составить программу которая на введенную дату выдает название...

Как извлечь URL из адресной строки? - JavaScript
Здравствуйте! Скажите, как извлекать и сохранять адрес из адресной строки браузера Фаерфокс, пользуясь imacroso'm? Какая команда нужна для...

Выбрать название города из строки - PHP
есть строки след. формата - Республика Беларусь, г.Минск (MSK-1) как составить регулярное выражение оставляющее только Город?

Извлечь из строки название директории - PHP
Всем привет. есть строчка $absfile = '/home/work/1.7z'; Как извлечь из этой строки папку? Допустим work

Нужно из строки типа '<src='dddd.gif' align='left' blabalbla>' извлечь только название файла - C# ASP.NET
Не могу написать грамотный паттерн: Нужно из строки типа '&lt;src='dddd.gif' align='left' blabalbla&gt;' извлечь только название файла, причем...

Поменять местами название второго города таблицы и последнего города, начинающегося на "Нов" - Visual Basic
Задан список из 10-ти городов. Поменять местами название второго города таблицы и последнего города, начинающегося на &quot;Нов&quot;. ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 14:42 #16
Цитата Сообщение от Excogit8er Посмотреть сообщение
PS. Скажи, а вот такое тоже решается через boost:regex?
Можно,но нет такой особой необходимости, ничто там не мешает считывать манипулируя потоками как ранее приведенный пример, не используя регулярки.

Добавлено через 1 минуту
Цитата Сообщение от Excogit8er Посмотреть сообщение
Аццкая жесть какая-то, особенно это регулярное выражение: boost::regex re("([[:digit:]]{0,6}),?\\s*(.*?)\\sг,(.*)");
Да основное время тратится именно на формирование этого выражения и его тестирование, зато код почти не меняется если фомат файла поменялся.

Я обычно заглядываю сюда http://regexpr.ru/cheatsheet/ , http://regexpr.ru/

Добавлено через 1 час 44 минуты
Кстати попробовал в VC++2010, работает если заменить и с std::regex
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 15:13  [ТС] #17
Цитата Сообщение от Avazart Посмотреть сообщение
Можно,но нет такой особой необходимости, ничто там не мешает считывать манипулируя потоками как ранее приведенный пример, не используя регулярки.
Предыдущее, это которое с std::istringstream выше по теме?

Да основное время тратится именно на формирование этого выражения и его тестирование, зато код почти не меняется если фомат файла поменялся.
Я обычно заглядываю сюда http://regexpr.ru/cheatsheet/ , http://regexpr.ru/
Ага, спасибо. Чувствую, мне в ближайшее время есть что читать )

Кстати попробовал в VC++2010, работает если заменить и с std::regex
Вот прямо скопировать, заменив boost::regex на std::regex? У меня intellismart (или как его) сразу же подчеркивает слово regex, типа identifier undefined. Может нужно еще какие-нить #include прописать?
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 15:16 #18
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "stdafx.h"
#include <windows.h>
 
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <regex>
 
using namespace std;
//----------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
::system("chcp 1251");
ifstream ifs("1.txt");
if(!ifs) { cerr<<"file not found"<<endl; return 0; }
 
 
string s;
string sre= "([[:digit:]]{0,6}),?\\s*(.*?)\\sг,(.*)";
 
regex re(sre);
smatch m;
 
while (getline(ifs,s) &&  regex_search(s,m,re) )
  {
    cout<<"<"<< m[1] <<">  ["<<m[2]<<"]"<<endl;
  }
    
::system("pause");
return 0;
}
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 17:02  [ТС] #19
Цитата Сообщение от Avazart Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "stdafx.h"
#include <windows.h>
 
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <regex>
 
using namespace std;
//----------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
::system("chcp 1251");
ifstream ifs("1.txt");
if(!ifs) { cerr<<"file not found"<<endl; return 0; }
 
 
string s;
string sre= "([[:digit:]]{0,6}),?\\s*(.*?)\\sг,(.*)";
 
regex re(sre);
smatch m;
 
while (getline(ifs,s) &&  regex_search(s,m,re) )
  {
    cout<<"<"<< m[1] <<">  ["<<m[2]<<"]"<<endl;
  }
    
::system("pause");
return 0;
}

В общем, ничего не подчеркивается и даже комплируется. Но и в консоль ничего не выводится при запуске )
При этом файл я, само собой, переименовал (и закрыл после цикла while)

Кстати, воспользовался твоим советом, скачал инсталлятор boost'a, отметил там при установке, что нужна именно 2010 и выставил галочки multithreaded, single threaded и прочее. Все установилось, но тока никаких бустов VS не видит ни фига, видимо, там вручную надо прописывать пути к директориям и библиотекам. Я думал, исталлятор избавляет от этой приятной задачи... Нах он тогда нужен - вообще не ясно.
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 17:07 #20
Цитата Сообщение от Excogit8er Посмотреть сообщение
В общем, ничего не подчеркивается и даже комплируется. Но и в консоль ничего не выводится при запуске )
При этом файл я, само собой, переименовал (и закрыл после цикла while)
Ну не знаю если файл находится, значит нет совпадений с регуляркой.
Может содержание файла изменилось?

Цитата Сообщение от Excogit8er Посмотреть сообщение
Все установилось, но тока никаких бустов VS не видит ни фига, видимо, там вручную надо прописывать пути к либам и библиотекам.
Ну я об этом и говорил что нужно прописывать пути руками в проекте как и для любой сторонней либы...
Цитата Сообщение от Excogit8er Посмотреть сообщение
Я думал, исталлятор избавляет от этой приятной задачи... Нах он тогда нужен - вообще не ясно.
Чтоб не компилировать исходники вручную ...
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 17:34  [ТС] #21
Цитата Сообщение от Avazart Посмотреть сообщение
Ну не знаю если файл находится, значит нет совпадений с регуляркой.
Может содержание файла изменилось?
Не, не менялось. Почему-то в этом цикле while вообще ничего не выводится в консоль. Попробовал просто строчку текста вывести, добавив к первой: cout << "test";
Не выводится. А вне цикла - все ок.


Ну я об этом и говорил что нужно прописывать пути руками в проекте как и для любой сторонней либы...

Чтоб не компилировать исходники вручную ...
А, ну ясно. Т.е. прописывать все-таки нужно? А что именно? Скажем, по адресу VC++ Directories -> Include Directories у меня сейчас прописано: "$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include;"
И что нужно добавить? А главное - прописать пути в Include Directories и Library Directories - и все, или ещё что-то где-то надо прописывать-добавлять?
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 17:36 #22
Включения и либы у меня это
Код
C:\Program Files\boost\boost_1_50
C:\Program Files\boost\boost_1_50\lib\
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 18:04  [ТС] #23
Цитата Сообщение от Avazart Посмотреть сообщение
Включения и либы у меня это
Код
C:\Program Files\boost\boost_1_50
C:\Program Files\boost\boost_1_50\lib\
Дык а как это - прямо так и прописывать? Там жеж какой-то свой формат, из серии: ;$(FrameworkSDKDir)\include;"
Что добавить: ;$(C:\Program Files\boost\boost_1_50)\include;" ??
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 18:05 #24
Так и писать ( без $ и скобок ) , т.е добавить
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 18:09  [ТС] #25
Цитата Сообщение от Avazart Посмотреть сообщение
Так и писать ( без $ и скобок ) , т.е добавить
А слово include нужно? Ну, т.е. вот такую строку добавить:

(C:\Program Files\boost\boost_1_50)\include;

?
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 18:12 #26
Именно так
Код
C:\Program Files\boost\boost_1_50
C:\Program Files\boost\boost_1_50\lib\
без всякого творчества...

Первую строчку во включение, вторую в либы.
1
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 18:16  [ТС] #27
Цитата Сообщение от Avazart Посмотреть сообщение
Именно так
Код
C:\Program Files\boost\boost_1_50
C:\Program Files\boost\boost_1_50\lib\
без всякого творчества...

Первую строчку во включение, вторую в либы.
Добавил. Ни фига ) Если в проекте прописать: #include <boost/regex.hpp>
подчеркивает, жалуясь на "cannot open source file "boost/regex.hpp"

PS А, тьфу блин, у меня же путь другой (не 1_50, а 1_51)

PPS Вот, теперь другое дело (ну, в смысле - ничего не подчеркивает)
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 18:18 #28
Значит не правильно прописал ...

Ты хоть проверил может у тебя буст в другом месте установился или папки не так называются...
0
Excogit8er
2 / 2 / 0
Регистрация: 23.10.2012
Сообщений: 66
26.12.2012, 18:26  [ТС] #29
Цитата Сообщение от Avazart Посмотреть сообщение
Значит не правильно прописал ...

Ты хоть проверил может у тебя буст в другом месте установился или папки не так называются...
Да не, все ок. Спасибо тебе за советы. Уже поправил и перекомпилил первый твой вариант(ну, в смысле - полностью), который:

C++
1
boost::regex re("([[:digit:]]{0,6}),?\\s*(.*?)\\sг,(.*)");
А инклюд <regex> выкинул нафиг, чтобы какого-нить конфликта имен не было.

Все компилится и даже результат похож: хрен че выводится в консоль))
Что уже неплохо)
0
Avazart
Эксперт С++
7188 / 5362 / 280
Регистрация: 10.12.2010
Сообщений: 23,666
Записей в блоге: 17
26.12.2012, 18:31 #30
Насчет std::regex std::regex и boost::regex

Добавлено через 2 минуты
Цитата Сообщение от Excogit8er Посмотреть сообщение
Все компилится и даже результат похож: хрен че выводится в консоль))
Что уже неплохо)
Странно, но это говорит только о том что совпадений не находит, значит либо опечатка ли регулярка не подходит по файл.

Кстати регулярки чувствительны к локали... т.е к кодировке файла
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.12.2012, 18:31
Привет! Вот еще темы с ответами:

Объявить класс «Вокзал» с указанием полей: название вокзала, местонахождение (название города), число направлений, поток пассажиров. - Pascal
Объявить класс «Вокзал» с указанием полей: название вокзала, местонахождение (название города), число направлений, поток пассажиров....

Название сайта в адресной строке - HTML, CSS
Здравствуйте! Встречал ни раз сайты, в адресной строке которых, вместо адреса сайта (типа http://aaa.ru) красуется название их сайта. ...

Получить название города - JavaScript
Ребята подскажите как можно сделать что бы получить название города из строк такого типа: 211391 Орша, Ленина, д.XX Орша, улица...

Парсинг Яндекс.Погоды | Опредленного города - C#
Доброго времени суток. Как можно спарсить восход и закат? &lt;sunrise&gt;07:03&lt;/sunrise&gt; &lt;sunset&gt;15:50&lt;/sunset&gt; Как получить данные с...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
26.12.2012, 18:31
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru