Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как из текстовой строки вытащить подстроку
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Димон Безпарольный
Есть допустим строка:

Код
unsigned char HTTPStr[] = "setting.html?SSID=sd&PASSWORD=dsd&NOTE=sds";



Нужно вытащить из нее sd и dsd.

Делаю так:

Код
int LeechPar(char* SrsBuf, char* Template, char* DestBuf)

{
    int T = strstr((const char*)SrsBuf, Template) + (strlen(Template));
    if(!T) {return 0;}
    int T1 = strstr((const char*)T,"&");
    if(!T1) {return 0;}
    int T2 = T1 - T;
        if(T2 > 20){return 0;}
    memcpy(DestBuf, T, T2);
    DestBuf[T2] = 0;
    return T2;
}

int main (void)
{    

    char Buf[20];

    //int T = strstr((const char*)HTTPStr,"SSID=") + 5;
    //int T1 = strstr((const char*)T,"&");
    //memcpy(Buf, T, T1 - T);
    //Buf[T1 - T] = 0;
    
    int P = LeechPar(HTTPStr, "SSID=", Buf);
    printf("\n%s %d\n", Buf, P);            

    P = LeechPar(HTTPStr, "PASSWORD=", Buf);
    printf("\n%s %d\n", Buf, P);    

}


Какие могут быть подводные камни? И может быть есть способ проще?
scifi
Код
sscanf(HTTPStr, "setting.html?SSID=[^&]&PASSWORD=[^&]", ssid, pass);
Димон Безпарольный
Если так, то что - то не получается:

Код
    char ssid[20];
    char pass[20];    
    sscanf(HTTPStr, "setting.html?SSID=[^&]&PASSWORD=[^&]", ssid, pass);
    printf("\n%s\n", ssid);


Но идея хорошая. Это работает:

Код
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

char *tokenstring = "first,25.5,second,15";
int result, i;
double fp;
char o[10], f[10], s[10], t[10];

void main()
{
   result = sscanf(tokenstring, "%[^','],%[^','],%[^','],%s", o, s, t, f);
   fp = atof(s);
   i  = atoi(f);
   printf("%s\n %lf\n %s\n %d\n", o, fp, t, i);
}
aaarrr
Цитата(Димон Безпарольный @ Sep 7 2017, 18:02) *
Но идея хорошая.

Плохая: контроля переполнения нет, а чудес у вас и без того хватает, как можно было заметить.
Димон Безпарольный
Цитата(aaarrr @ Sep 7 2017, 19:09) *
Плохая: контроля переполнения нет, а чудес у вас и без того хватает, как можно было заметить.

Нда. Возможно так. Если других способов нет... Мой то наверно не лучше.
aaarrr
Цитата(Димон Безпарольный @ Sep 7 2017, 18:11) *
Мой то наверно не лучше.

Ну, если ошибки убрать, то ничего. Сейчас причешем.
Димон Безпарольный
Некоторые убрал:

Код
unsigned char HTTPStr[] = "+IPD,0,471:GET /setting.html?SSID=77&PASSWORD=5 HTTP/1.1";

int LeechPar(char* SrsBuf, char* Template, char* Template1, char* DestBuf)

{
    int T = strstr((const char*)SrsBuf, Template);
    if(!T) {return 0;}
    T = T + (strlen(Template));
    int T1 = strstr((const char*)T, Template1);
    if(!T1) {return 0;}
    int T2 = T1 - T;
    if(T2 > 20){return 0;}
    memcpy(DestBuf, T, T2);
    DestBuf[T2] = 0;
    return T2;
}

int main (void)
{    

    char Buf[20];
    
    int P = LeechPar(HTTPStr, "SSID=", "&", Buf);
    printf("\n%s %d\n", Buf, P);            

    P = LeechPar(HTTPStr, "PASSWORD=", " HTTP", Buf);
    printf("\n%s %d\n", Buf, P);    

}
aaarrr
Цитата(Димон Безпарольный @ Sep 7 2017, 18:19) *
Некоторые убрал:

4 warning'а, 1 note и Segmentation Fault на 64 битной машине...

Проще надо быть:
Код
#include <stdio.h>
#include <string.h>

unsigned char HTTPStr[] = "setting.html?SSID=sd&PASSWORD=dsd&NOTE=sds";

int LeechPar(char* SrsBuf, char* Template, char* DestBuf, int n)
{
    char *src = strstr((const char*)SrsBuf, Template), c;
    int i;

    if(src)
    {
        src += strlen(Template);
        for(i = 0; i < n; i++)
        {
            c = src[i];
            if(c)
            {
                if(c == '&')
                {
                    DestBuf[i] = '\0';
                    return i;
                }
                DestBuf[i] = c;
            }
            else return 0;
        }
    }
    return 0;
}

int main(int argc, char *argv[])
{    
    char Buf[20];

    int P = LeechPar(HTTPStr, "SSID=", Buf, sizeof(Buf));
    printf("\n%s %d\n", Buf, P);            

    P = LeechPar(HTTPStr, "PASSWORD=", Buf, sizeof(Buf));
    printf("\n%s %d\n", Buf, P);    

}
Димон Безпарольный
Сломал голову, что такое с и чему оно равно в строке:

Код
    char *src = strstr((const char*)SrsBuf, Template), c;


С исходной строкой:

Код
unsigned char HTTPStr[] = "setting.html?SSID=sd&PASSWORD=dsd&NOTE=sds";


Работает. А со строкой:
Код
unsigned char HTTPStr[] = "+IPD,0,471:GET /setting.html?SSID=5&PASSWORD=5 HTTP/1.1";


Уже нет. Выдает:

Цитата
5 1

5 HTTP/1.1  b◄kv─[pv4¶@ 0


Я добавил Template1 потому что он разный. Во втором случае он " HTTP". Видимо от сюда и глюк.
scifi
Цитата(aaarrr @ Sep 7 2017, 18:09) *
Плохая: контроля переполнения нет

Издеваетесь? У сканфа есть средства для этого. Лень в справочник заглянуть? Или вам надо предъявить все до последней запятой? Нет уж, увольте.
aaarrr
Цитата(scifi @ Sep 7 2017, 19:07) *
Издеваетесь? У сканфа есть средства для этого. Лень в справочник заглянуть? Или вам надо предъявить все до последней запятой? Нет уж, увольте.

Берегите нервы. Идея нормальная, реализация - увы.

Цитата(Димон Безпарольный @ Sep 7 2017, 18:41) *
Сломал голову, что такое с и чему оно равно в строке:

Код
    char *src = strstr((const char*)SrsBuf, Template), c;

Переменная типа char. Ничему не равна.

Цитата(Димон Безпарольный @ Sep 7 2017, 18:41) *
С исходной строкой:

Код
unsigned char HTTPStr[] = "setting.html?SSID=sd&PASSWORD=dsd&NOTE=sds";


Работает. А со строкой:
Код
unsigned char HTTPStr[] = "+IPD,0,471:GET /setting.html?SSID=5&PASSWORD=5 HTTP/1.1";


Уже нет.

Так определитесь с критериями определения конца поля.
Димон Безпарольный
Цитата(aaarrr @ Sep 7 2017, 20:34) *
Так определитесь с критериями определения конца поля.

Конец поля увы оказался разный. Для этого и Template1
aaarrr
Цитата(Димон Безпарольный @ Sep 7 2017, 19:48) *
Конец поля увы оказался разный. Для этого и Template1

Подозреваю, что число вариантов все же конечное, и можно обойтись без Template1.
Димон Безпарольный
Цитата(aaarrr @ Sep 7 2017, 21:17) *
Подозреваю, что число вариантов все же конечное, и можно обойтись без Template1.

Я пока и сам не знаю сколько их.
timurey
Довольно простой парсер (взято отсюда: http://we.easyelectronics.ru/electro-and-p...ttp-i-cgi.html)

Код
char *url, *p, *params,

// Разбираем URL на путь и параметры
if((params = strchr(url, '?')))
    *(params++) = 0;

// Разбираем параметры
while(params)
{
     // Смотрим где заканчивается параметр
    if((p = strchr(params, '&')))
        *(p++) = 0;
                
    // Разбираем параметр на имя и значение
    name = params;
    if((value = strchr(name, '=')))
        *(value++) = 0;
                
    // Параметр = led (on/off)?
    if( (strcmp(name, "led") == 0 ) && value )
    {
        if(strcmp(value, "on") == 0)
            led_on()
        else if(strcmp(value, "off") == 0)
            led_off()
     }
                
     // Параметр = lang (en/ru)?
     else if( (strcmp_P(name, PSTR("lang")) == 0) && value )
     {
         if(strcmp_P(value, "en") == 0)
             lang_ru = 0;
         else if(strcmp_P(value, "ru") == 0)
             lang_ru = 1;
      }
                
      // Переходим к следующему параметру
      params = p;
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.