Перейти к содержанию
    

Как из текстовой строки вытащить подстроку

Есть допустим строка:

 

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

}

 

Какие могут быть подводные камни? И может быть есть способ проще?

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если так, то что - то не получается:

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но идея хорошая.

Плохая: контроля переполнения нет, а чудес у вас и без того хватает, как можно было заметить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Плохая: контроля переполнения нет, а чудес у вас и без того хватает, как можно было заметить.

Нда. Возможно так. Если других способов нет... Мой то наверно не лучше.

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мой то наверно не лучше.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Некоторые убрал:

 

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

}

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Некоторые убрал:

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". Видимо от сюда и глюк.

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Плохая: контроля переполнения нет

Издеваетесь? У сканфа есть средства для этого. Лень в справочник заглянуть? Или вам надо предъявить все до последней запятой? Нет уж, увольте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Издеваетесь? У сканфа есть средства для этого. Лень в справочник заглянуть? Или вам надо предъявить все до последней запятой? Нет уж, увольте.

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

 

Сломал голову, что такое с и чему оно равно в строке:

 

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

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

 

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

 

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";

 

Уже нет.

Так определитесь с критериями определения конца поля.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так определитесь с критериями определения конца поля.

Конец поля увы оказался разный. Для этого и Template1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конец поля увы оказался разный. Для этого и Template1

Подозреваю, что число вариантов все же конечное, и можно обойтись без Template1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подозреваю, что число вариантов все же конечное, и можно обойтись без Template1.

Я пока и сам не знаю сколько их.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Довольно простой парсер (взято отсюда: 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...