The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"sscanf парсер"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"sscanf парсер"  +/
Сообщение от microbash (ok) on 08-Июл-15, 12:32 
Прошу совета как получить желаемый результат.

Код такой:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char  p1[100];

char *soap=
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<rows> <row> AAA <row> <row> BBB <row> </rows>\
</soap:Body>\
</soap:Envelope>\
";

char *soap_template =
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<rows> %s </rows>\
</soap:Body>\
</soap:Envelope>\
";

int main()
{

   sscanf( soap, soap_template, &p1);

   printf("%s",p1);
   printf("\n");

   return(0);
}


Результат:
<row>

Желаемый результат:
<row> AAA <row> <row> BBB <row>


Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "sscanf парсер"  +/
Сообщение от fail on 08-Июл-15, 13:53 
> Прошу совета как получить желаемый результат.
> char *soap=
> "\
> <soap:Envelope>\
>  <soap:Header>\
>  </soap:Header>\
>  <soap:Body>\
>  <rows> <row> AAA <row> <row> BBB <row> </rows>\

для начала, а не <row> AAA </row> <row> BBB </row> ?

>  </soap:Body>\
>  </soap:Envelope>\
> ";

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "sscanf парсер"  +/
Сообщение от microbash (ok) on 08-Июл-15, 14:22 
У меня есть как бы блок записей. Этих записей заранее неизвестно сколько, от 0 до 20 например. Также есть могу добавить тег с количеством этих записей. Например так:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char  p1[100], p2[100];

char *soap=
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<count> 2 </count>
<rows> <row> AAA <row> <row> BBB <row> </rows>\
</soap:Body>\
</soap:Envelope>\
";

char *soap_template =
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<count> %s </count>
<rows> %s </rows>\
</soap:Body>\
</soap:Envelope>\
";

int main()
{

   sscanf( soap, soap_template, &p1, &p2);

   printf("%s %s",p1,p2);
   printf("\n");

   return(0);

Если вы предлагает рассмотреть второй вариант без тегов <rows> </rows>, то как к нему задать шаблон при переменном значении записей?


Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

5. "sscanf парсер"  +/
Сообщение от fail on 08-Июл-15, 16:20 

> Если вы предлагает рассмотреть второй вариант без тегов <rows> </rows>, то как
> к нему задать шаблон при переменном значении записей?

Честно говоря со sscanf() не пересекался плотно,
взгляд резануло вот это :
>> <rows> <row> AAA <row> <row> BBB <row> </rows>

<row> AAA <row> <= закрывающий тег - нету ?!
<row> BBB <row> <= ... тоже

P.S.:
из man sscanf
...
s Matches a sequence of non-white-space characters; the next pointer must be a pointer  to char, and the array must be large enough to accept all the sequence and the termi-
nating  NUL character.  The input string stops at white space or at the maximum field width, whichever occurs first.
...

если правильно понял, должно быть что-то вроде { без пробальных символов(пробел, табуляция и т.д.) }:
...<rows><row>AAA</row><row>BBB</row></rows>...

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

9. "sscanf парсер"  +/
Сообщение от microbash (??) on 08-Июл-15, 19:47 
Закрывающиеся теги есть конечно. Это ошибка в моем описании.
Вот верный вариант.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char  p1[100], p2[100];

char *soap=
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<count> 2 </count>
<rows> <row> AAA </row> <row> BBB </row> </rows>\
</soap:Body>\
</soap:Envelope>\
";

char *soap_template =
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<count> %s </count>
<rows> %s </rows>\
</soap:Body>\
</soap:Envelope>\
";

int main()
{

   sscanf( soap, soap_template, &p1, &p2);

   printf("%s %s",p1,p2);
   printf("\n");

   return(0);

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

6. "sscanf парсер"  +/
Сообщение от fail on 08-Июл-15, 16:30 
> Если вы предлагает рассмотреть второй вариант без тегов <rows> </rows>, то как
> к нему задать шаблон при переменном значении записей?

Думается,
вариант из вопроса (самый первый)

>> <rows> <row> AAA <row> <row> BBB <row> </rows>\

отсюда пробелы нафиг.

P.S.:
читаем мануалы внимательней


Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

12. "sscanf парсер"  –1 +/
Сообщение от microbash (??) on 08-Июл-15, 20:35 
Пока не совсем понимаю разницу с пробелами и без. Результат вроде бы одинаковый. Или не совсем?


Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

13. "sscanf парсер"  +/
Сообщение от fail_ on 08-Июл-15, 21:23 
> Пока не совсем понимаю разницу с пробелами и без. Результат вроде бы
> одинаковый. Или не совсем?

due to ( man sscanf ):

...
s Matches a sequence of non-white-space characters; the next pointer must be a pointer  to char, and the array must be large enough to accept all the sequence and the termi-
nating  NUL character.  The input string stops at white space or at the maximum field width, whichever occurs first.
...

имo, причиниа в этом - Matches a sequence of non-white-space characters...

Из:
>> Прошу совета как получить желаемый результат.
>> Код такой:
>> ...
>> <rows> <row> AAA <row> <row> BBB <row> </rows>\

заменить на
<rows> <row>AAA</row><row>BBB</row> </rows>\

Ответить | Правка | ^ к родителю #12 | Наверх | Cообщить модератору

14. "sscanf парсер"  +/
Сообщение от microbash (ok) on 09-Июл-15, 08:03 
Большое спасибо за идеи.
Тут ключ к пониманию - "The input string stops at white space".
Теперь сделал вот так:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char  p1[100];

char *soap=
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<rows>\
<row>AAA</row>\
<row>BBB</row>\
<row>CCC</row>\
<row>DDD</row>\
<row>EEE</row>\
<row>FFF</row>\
<row>GGG</row>\
<row>JJJ</row>\
<row>HHH</row>\
</rows>\               // One white space before </rows> for stop input
</soap:Body>\
</soap:Envelope>\
";

char *soap_template =
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<rows>%s</rows>\
</soap:Body>\
</soap:Envelope>\
";

int main()
{

   sscanf( soap, soap_template, &p1);

   printf("%s",p1);
   printf("\n");

   return(0);
}

Результат:
<row>AAA</row><row>BBB</row><row>CCC</row><row>DDD</row><row>EEE</row><row>FFF</row><row>GGG</row><row>JJJ</row><row>HHH</row>

На данной стадии вполне годится. :)

Ответить | Правка | ^ к родителю #13 | Наверх | Cообщить модератору

15. "sscanf парсер"  +/
Сообщение от fail on 09-Июл-15, 09:30 
> Большое спасибо за идеи.
> Тут ключ к пониманию - "The input string stops at white space".

и

"Matches a sequence of non-white-space characters "

> Результат:
> <row>AAA</row><row>BBB</row><row>CCC</row><row>DDD</row><row>EEE</row><row>FFF</row><row>GGG</row><row>JJJ</row><row>HHH</row>
> На данной стадии вполне годится. :)

Ответить | Правка | ^ к родителю #14 | Наверх | Cообщить модератору

19. "sscanf парсер"  +/
Сообщение от microbash (??) on 11-Июл-15, 13:10 
Вообщем в итоге пока приостановил опыты с sscanf, т.к. есть претензии к его функционалу.
Неоднозначные результаты на различные входящие данные.
:(


Ответить | Правка | ^ к родителю #15 | Наверх | Cообщить модератору

3. "sscanf парсер"  +/
Сообщение от Andrey Mitrofanov on 08-Июл-15, 14:46 
> Желаемый результат:
> <row> AAA <row> <row> BBB <row>

 <soap:Body>\
-<rows> %s </rows>\
+<rows> %31c </rows>\
</soap:Body>\

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

4. "sscanf парсер"  +/
Сообщение от microbash (ok) on 08-Июл-15, 15:40 
Решение оригинальное, но к сожалению подходит только под конкретные исходные данные.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char  p1[100];

char *soap=
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<rows>\
<row> AAA </row>\
<row> BBB </row>\
<row> CCC </row>\
<row> DDD </row>\
<row> EEE </row>\
</rows>\
</soap:Body>\
</soap:Envelope>\
";

char *soap_template =
"\
<soap:Envelope>\
<soap:Header>\
</soap:Header>\
<soap:Body>\
<rows> %200c </rows>\
</soap:Body>\
</soap:Envelope>\
";

int main()
{

   sscanf( soap, soap_template, &p1);

   printf("%s",p1);
   printf("\n");

   return(0);
}


Результат:
<row> AAA </row> <row> BBB </row> <row> CCC </row> <row> DDD </row> <row> EEE </row> </rows> </soap:Body> </soap:Envelope>


Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

7. "sscanf парсер"  +/
Сообщение от Andrey Mitrofanov on 08-Июл-15, 18:19 
> Прошу совета как получить желаемый результат.
>    sscanf( soap, soap_template, &p1);
> Результат:
> <row>
> Желаемый результат:
> <row> AAA <row> <row> BBB <row>

Я извиняюсь, именно Си и именно scanf() обязательны?

Если можно шеллом с пайпом, то 1 grep (чтоб токенизацию не делать awk-ом) + 1 awk в одну строку.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

8. "sscanf парсер"  +/
Сообщение от Andrey Mitrofanov on 08-Июл-15, 18:22 
>в одну строку.

&& забить на таги Envelope/Header/Body.

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

10. "sscanf парсер"  +/
Сообщение от microbash (??) on 08-Июл-15, 19:51 
Нужен C или С++, т.е. универсальный компилятор, который работает на любой платформе, в том числе мобильной. Я не хочу быть привязан к платформе или к ОС.

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

11. "sscanf парсер"  +/
Сообщение от Andrey Mitrofanov on 08-Июл-15, 19:55 
> Нужен C или С++, т.е. универсальный компилятор, который работает на любой платформе,

Парсеры пишет bison, токенайзеры - flex. Определяешь грамматику - и вперёд!

> в том числе мобильной. Я не хочу быть привязан к платформе или к ОС.

А ещё можешь iZEN-а позвать и попилить с ним на джавве прямо на форуме. Показательно.

++Дедушка Мо^WяЗЕН, выходи!

Ответить | Правка | ^ к родителю #10 | Наверх | Cообщить модератору

16. "sscanf парсер"  +/
Сообщение от Alex_S (??) on 10-Июл-15, 04:47 
>> Нужен C или С++, т.е. универсальный компилятор, который работает на любой платформе,
> Парсеры пишет bison, токенайзеры - flex. Определяешь грамматику - и вперёд!
>> в том числе мобильной. Я не хочу быть привязан к платформе или к ОС.
> А ещё можешь iZEN-а позвать и попилить с ним на джавве прямо
> на форуме. Показательно.
> ++Дедушка Мо^WяЗЕН, выходи!

кстати, чо ,  strtok  щас чо, некошерен ?   можно ж , накрайняк .

Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

17. "sscanf парсер"  –1 +/
Сообщение от microbash (??) on 10-Июл-15, 10:38 
Каким образом из strtok можно получить простой xml-парсер?


Ответить | Правка | ^ к родителю #16 | Наверх | Cообщить модератору

18. "sscanf парсер"  +/
Сообщение от Andrey Mitrofanov on 10-Июл-15, 18:20 
> Каким образом из strtok можно получить простой xml-парсер?

Программированием и, по необходимости, упрощением.

Впрочем, попробуйте Ваш способ -- ждать удовлетворяющего Вас решения на форуме.

Ответить | Правка | ^ к родителю #17 | Наверх | Cообщить модератору

20. "sscanf парсер"  +/
Сообщение от microbash (??) on 11-Июл-15, 13:20 
Ну почему же сразу "ждать на форуме".
На форуме я задаю вопрос с тем чтобы услышать мнение людей, у которых уже есть опыт.
Сам конечно тоже самостоятельно веду поиски.
Сейчас нашел вроде бы неплохой легковесный парсер на С: http://dev.yorhel.nl/yxml
Пока с ним эспериментирую.

Ответить | Правка | ^ к родителю #18 | Наверх | Cообщить модератору

21. "sscanf парсер"  +/
Сообщение от igor (??) on 27-Июл-15, 11:20 
> int main()
> {
>    sscanf( soap, soap_template, &p1);
>    printf("%s",p1);
>    printf("\n");
>    return(0);
> }

Встречный вопрос: чем не угодил libxml2 (XPath) или libexpat ?


Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

22. "sscanf парсер"  +/
Сообщение от pavlinux (ok) on 16-Авг-15, 02:17 
> Встречный вопрос: чем не угодил libxml2 (XPath) или libexpat ?

Сшник должен написать всё сам.
В конечном итоге должен получиться гигабайтный с-файлик с 1000000 #define,
но умеющий партисить гигабайтный XML за мильярд тактов процессора.

Ответить | Правка | ^ к родителю #21 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Спонсоры:
Слёрм
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2020 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру