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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
#1

парсер - C++

15.12.2012, 21:02. Просмотров 1200. Ответов 15
Метки нет (Все метки)

Добрый день, у меня возникла вот такая вот проблема...
При работе парсера, он разделяет строки как и задуманно, но появляются непредвиденные символы, невезь откуда.
Скорее всего подозрение падает на преобразование типа char -> char *
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
int s_pars::Position(char symb,char *buff,int b_size)
{
    for (int i=0;i<b_size;i++)
    {
        if(i<2&&buff[i]=='/')
        {return -2;} // Код коментариев.
        if(buff[i]==symb)
        {return i;}
    }
    return -1;
}
int s_pars::ExtractString(char *buff,char *r_buff,int b_size, int pos1,int pos2,  bool d_mode)
{
int y=0;
int i;
for (i=pos1;i<pos2&&i<b_size;i++)
{
    r_buff[y]=buff[i];
    y++;
}
if(d_mode) //смещаем данные
{
    for(int x=0;x<=pos2;x++)
    {
        if(pos2+x!=b_size)
        {
            buff[x]=buff[pos2+x];
        }
    }
}
return 0;
}
C++
1
2
3
4
5
6
7
gus21rus@NeuralComputer:~/Рабочий стол/Проекты/cheb21client/bin/Release$ ./cheb21client
Запуск приложения...
Thread started!
Начало конфигурации системы
Открытие конфигурационного файла: ОК
Чтение данных: Entering param LOADGUI|UУїпїЅ{e buff LOADGUI=true;
gus21rus@NeuralComputer:~/Рабочий стол/Проекты/cheb21client/bin/Release$
Использую сиауты что бы просмотреть что там находится, получаю вот данный вывод...
p.s Entering param LOADGUI|Uӿ�{e buff LOADGUI=true;

преобразование типа имеет следующий вид
C++
1
2
3
pars.ExtractString((char *)buff,&param[0],sizeof(buff),0,pos2,false);
раньше было
pars.ExtractString((char *)buff,(char *)param,sizeof(buff),0,pos2,false);
Данный парсер предназначен для конфигурирования системы принципом параметр=аргумент;

Добавлено через 3 часа 59 минут
эм, я может что то не так написал, если не получил еще ответа?)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.12.2012, 21:02     парсер
Посмотрите здесь:

C++ Парсер HTML на C++
C++ Парсер
C++ Парсер
C++ парсер строки
Парсер HTML C++
C++ Наипростейший парсер
C++ Парсер паскаля
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.12.2012, 21:18     парсер #2
Цитата Сообщение от Gus Посмотреть сообщение
i<b_size
А если попробовать i < b_size + 1

Добавлено через 1 минуту
Цитата Сообщение от go Посмотреть сообщение
А если попробовать i < b_size + 1
Нет, бред сказал. Прокомментируйте каждый параметр в вызываемой функции и и покажите их объявление.

Добавлено через 1 минуту
Gus, кароче мне кажется, что Вы теряете '\0'

Добавлено через 16 секунд
Цитата Сообщение от go Посмотреть сообщение
А если попробовать i < b_size + 1
И возможно это не бред.
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
15.12.2012, 21:25  [ТС]     парсер #3
пробывал! да проблема исчезает. последний символ стирается.

C++
1
2
3
4
5
6
7
8
if(strcmp(param,"LOADGUI")==0)
{
pars.ExtractString((char *)buff,(char *)arg,sizeof(buff),
                   pars.Position('=',(char *)buff,sizeof(buff)),
                   pars.Position(';',(char *)buff,sizeof(buff)),true);
                   cout <<"GUI CHECKED!"<<endl;
                   if(strcmp(arg,"true")==0){cout <<"OK"<<endl;}}
}
C++
1
pars.ExtractString((char *)buff,&param[0],sizeof(buff),0,pos2,false);
Два места откуда они вызываются.

Добавлено через 6 минут
так ваши слова не сразу понял коментирую.
ExtractString - 1 агрумент указатель входного буфера типа чара, где содержится строка
2 агрумент возвращаемый указатель.
3 Размер буффера (что бы не вылетел из массива)
4 начальная позиция (int)
5 конечная позиция (int)
6 сместить ли массив данных, на длину вырезанной строки(кол во символов) (bool)
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.12.2012, 21:30     парсер #4
Цитата Сообщение от Gus Посмотреть сообщение
пробывал! да проблема исчезает. последний символ стирается.
Так а что сейчас случилось?

Добавлено через 1 минуту
Gus, Си-строка нуль-терминированная. Вы должны сами доставить нуль-терминатор.
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
15.12.2012, 21:36  [ТС]     парсер #5
попробуем... тогда с \0

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int s_pars::ExtractString(char *buff,char *r_buff,int b_size, int pos1,int pos2,  bool d_mode)
{
int y=0;
int i;
for (i=pos1;i<pos2&&i<b_size;i++)
{
    r_buff[y]=buff[i];
    y++;
}
if(d_mode) //смещаем данные
{
    for(int x=0;x<=pos2;x++)
    {
        if(pos2+x!=b_size)
        {
            buff[x]=buff[pos2+x];
        }
    }
}
strcat(r_buff,'\0');
return 0;
}
Segmentation fault (core dumped)
хотя не правильно сделал, сейчас по другому попробую.
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
15.12.2012, 21:38     парсер #6
да, работа с голыми указателями - она такая. чревата крашами и глюками.
почему вы не пользуетесь скажем std::string? планируете парсить миллионы строк и это типа оптимизация?
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
15.12.2012, 21:40  [ТС]     парсер #7
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int s_pars::ExtractString(char *buff,char *r_buff,int b_size, int pos1,int pos2,  bool d_mode)
{
int y=0;
int i,x;
for (i=pos1;i<pos2&&i<b_size;i++)
{
    r_buff[y]=buff[i];
    y++;
}
r_buff[i+1]='\0';
if(d_mode) //смещаем данные
{
    for(x=0;x<=pos2;x++)
    {
        if(pos2+x!=b_size)
        {
            buff[x]=buff[pos2+x];
        }
    }
}
buff[pos2+(++x)]='\0';
return 0;
}
так тоже особо не помогло..

Добавлено через 51 секунду
согласен затея г..но, но как то привычнее работать с чаром. да и понятнее для мну будет немного. что я делаю и почему я это делаю)
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
15.12.2012, 21:42     парсер #8
согласен затея г..но, но как то привычнее работать с чаром. да и понятнее для мну будет немного. что я делаю и почему я это делаю)
ну это вы зря. если утрировать эти слова, то можно казать что на ассемблере этот код будет понятнее.
стоит один раз освоить std::string и много много геморроя уйдет. к тому же осваивать там нечего,
все просто и понятно.
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.12.2012, 21:46     парсер #9
Цитата Сообщение от Gus Посмотреть сообщение
strcat(r_buff,'\0');
А ничего, что strcat сначало будет искать этот самый '\0' ?
C++
1
2
3
4
5
6
7
for (i=pos1;i<pos2&&i<b_size;i++)
{
    r_buff[y]=buff[i];
    y++;
}
 
r_buff[y] = '\0';
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
15.12.2012, 21:48  [ТС]     парсер #10
я пользовался string AnsiString но в конечном счете мне более по нраву char.

Добавлено через 1 минуту
Цитата Сообщение от go Посмотреть сообщение
А ничего, что strcat сначало будет искать этот самый '\0' ?
C++
1
2
3
4
5
6
7
for (i=pos1;i<pos2&&i<b_size;i++)
{
    r_buff[y]=buff[i];
    y++;
}
 
r_buff[y] = '\0';
C++
1
r_buff[i+1]='\0';
в ручную добавил
go
Эксперт C++
3586 / 1366 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
15.12.2012, 22:09     парсер #11
Цитата Сообщение от Gus Посмотреть сообщение
в ручную добавил
Получили желаемый результат?
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
15.12.2012, 22:11     парсер #12
вот накидал по быстрому примерно то, чего вы хотите сделать:
http://liveworkspace.org/code/4piPYI$4
задача свелась к подзадачкам:
нужно как-то перечислять строки из файла. делается. просто.
нужно более навороченный парсер, скажем чтобы строки 'key = value' были корректными.
ну и остается просто правильно интерпретировать строки в получившейся мапине.

это для сравнения. больше половина кода - это тупо обработка ошибок. без обработки все вообще трехстрочное.
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
16.12.2012, 00:46  [ТС]     парсер #13
но к сожалению проблема не ушла.

Добавлено через 2 часа 27 минут
зачем так жить если возникает ошибка Core dumped?
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
16.12.2012, 00:55     парсер #14
это типа ап такой чтоли?
вы сказали голые указатели вам понятнее и проще. вот радуйтесь. вроде все просто, но ошибится в индексах, залезть не в ту память и получить краш - это как здрасти.
более высокоуровневые классы придумали не от хорошей жизни. пользуйтесь ими.
и второй совет: освойте отладчик той среды, в которой работаете. подобного рода краши с отладчиком находятся и исправляются без особых проблем.
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
16.12.2012, 13:20  [ТС]     парсер #15
Кхмм. странно... в Debug режиме программа не выдает этой ошибки.
в режиме Release ошибка появляется.
Используется стандартный отладчик GDB
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.12.2012, 19:20     парсер
Еще ссылки по теме:

Простой парсер C++
C++ Парсер
Парсер аудиофайлов C++
C++ Парсер, utf-8
C++ JSON парсер С++

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

Или воспользуйтесь поиском по форуму:
Gus
24 / 35 / 2
Регистрация: 17.02.2009
Сообщений: 364
20.12.2012, 19:20  [ТС]     парсер #16
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
int s_pars::Position(char symb,char *buff)
{
//Функция поиска индекса позиции символа в строке.
for(int i=0;buff[i]!='\0'||buff[i]!='\n';i++) //перелистываем массив в поиске нашего символа. условие поиска. пока buff не будет ровняться символу завершения строки.
    if(buff[i]==symb) //Сравнивание каждого элемента массива, с символом поиска.
    {
    return i;   //если найден возвращаем его индекс.
    }
    return -1; //Если нет, то возвращаем -1 (сообщение того что символ не найден)
}
 
int s_pars::ExtractString(char *buff,char *r_buff,int pos1,int pos2,  bool d_mode)
{
//Функция изьятия подстроки из строки.
int y,i;
for(i=pos1;i!=pos2&&buff[i]!='\0';i++) //Перебираем массив, и вырезаем подстроку.
{
    r_buff[i-pos1]=buff[i]; //Вырезаем строчку
}
if(d_mode==true) //смещаем буффер
{
    for(i=pos2;buff[i]!='\n';i++,y++)
    {
    buff[y]=buff[i];
    buff[i]=0;
    }
    buff[i+1]='\0'; //Добавляем терминирующий знак
}
r_buff[pos2+1]='\0'; //добавляем терминирующий знак
}
Вот тут немного проработал, никаких вылетов из за предела замечено не было. но... непонятные символы добавляются до сих пор... про недочеты данного алгоритма я знаю, что если попадется строка немного длиньше, в которой нет терминирующего знака \0 выдаст, ошибку, это я поправлю.
как быть с данной проблемой по существу (появление загадочных символов)

Добавлено через 3 часа 34 минуты
up!!!

Добавлено через 1 час 11 минут
народ, эта проблема тормозит процесс разработки... помогите.

Добавлено через 44 минуты
Решил вроде бы, как проблему но не так как задумал...
Yandex
Объявления
20.12.2012, 19:20     парсер
Ответ Создать тему
Опции темы

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