The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
sscanf парсер, !*! microbash, 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>


  • sscanf парсер, !*! fail, 13:53 , 08-Июл-15 (1)
    > Прошу совета как получить желаемый результат.
    > 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>\
    > ";

    • sscanf парсер, !*! microbash, 14:22 , 08-Июл-15 (2)
      У меня есть как бы блок записей. Этих записей заранее неизвестно сколько, от 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>, то как к нему задать шаблон при переменном значении записей?


      • sscanf парсер, !*! fail, 16:20 , 08-Июл-15 (5)

        > Если вы предлагает рассмотреть второй вариант без тегов <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>...

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

          #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);

      • sscanf парсер, !*! fail, 16:30 , 08-Июл-15 (6)
        > Если вы предлагает рассмотреть второй вариант без тегов <rows> </rows>, то как
        > к нему задать шаблон при переменном значении записей?

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

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

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

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


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


          • sscanf парсер, !*! fail_, 21:23 , 08-Июл-15 (13)
            > Пока не совсем понимаю разницу с пробелами и без. Результат вроде бы
            > одинаковый. Или не совсем?

            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>\

            • sscanf парсер, !*! microbash, 08:03 , 09-Июл-15 (14)
              Большое спасибо за идеи.
              Тут ключ к пониманию - "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>

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

              • sscanf парсер, !*! fail, 09:30 , 09-Июл-15 (15)
                > Большое спасибо за идеи.
                > Тут ключ к пониманию - "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>
                > На данной стадии вполне годится. :)

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


  • sscanf парсер, !*! Andrey Mitrofanov, 14:46 , 08-Июл-15 (3)
    > Желаемый результат:
    > <row> AAA <row> <row> BBB <row>

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

    • sscanf парсер, !*! microbash, 15:40 , 08-Июл-15 (4)
      Решение оригинальное, но к сожалению подходит только под конкретные исходные данные.

      #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>


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

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

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

    • sscanf парсер, !*! Andrey Mitrofanov, 18:22 , 08-Июл-15 (8)
      >в одну строку.

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

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

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

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

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

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

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

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

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

          • sscanf парсер, !*! microbash, 10:38 , 10-Июл-15 (17) –1
            Каким образом из strtok можно получить простой xml-парсер?


            • sscanf парсер, !*! Andrey Mitrofanov, 18:20 , 10-Июл-15 (18)
              > Каким образом из strtok можно получить простой xml-парсер?

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

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

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

  • sscanf парсер, !*! igor, 11:20 , 27-Июл-15 (21)
    > int main()
    > {
    >    sscanf( soap, soap_template, &p1);
    >    printf("%s",p1);
    >    printf("\n");
    >    return(0);
    > }

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


    • sscanf парсер, !*! pavlinux, 02:17 , 16-Авг-15 (22)
      > Встречный вопрос: чем не угодил libxml2 (XPath) или libexpat ?

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




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

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