strstok

fsdb
Offline
Зарегистрирован: 24.10.2015


char *ssid ;  // Имя вайфай точки доступа
char *pass; // Пароль от точки доступа

char *mqtt_server; // Имя сервера MQTT
int  mqtt_port = 0; // Порт для подключения к серверу MQTT
char *mqtt_user; // Логи от сервер
char *mqtt_pass; // Пароль от сервера

String topic1,topic2,topic3,topic4,topic5,topic6,topic7,topic8,topic9,topic10;

.................

if ( (SerialBuff.indexOf("SetBegin")==0) and (SerialBuff.indexOf("SetEnd")>0) ) {


char charVar[SerialBuff.length()+1];
SerialBuff.toCharArray(charVar, sizeof(charVar));

char *sInput =(char *)charVar;


  int h1=0;
  for (char *p = strtok(sInput, "SetBegin_"); p; p = strtok(NULL, "SetEnd_")) {
    Serial.print(p);  Serial.print("+");
    
    if (h1==0) {ssid=p;}
    if (h1==1) {pass=p;}
    if (h1==2) {mqtt_server=p;}
    if (h1==3) {mqtt_port=atoi(p);}
    if (h1==4) {mqtt_user=p;}
    if (h1==5) {mqtt_pass=p;}
    if (h1==6) {topic1=String(p);}
    if (h1==7) {topic2=String(p);}
    if (h1==8) {topic3=String(p);}
    if (h1==9) {topic4=String(p);}
    if (h1==10) {topic5=String(p);}
    if (h1==11) {topic6=String(p);}
    if (h1==12) {topic7=String(p);}
    if (h1==13) {topic8=String(p);}
    if (h1==14) {topic9=String(p);}
    if (h1==15) {topic10=String(p);}
    
  


    h1++;       
  }

}

Ребята помогите пожалуйста разобраться

Подаю на входе: SetBegin_router_777877787778_m14.cloudmqtt.com_19821_fdsocrnr_1ER1MwEsUMip_test/temp_SetEnd_

Получаю на выходе: rou+r+777877787778+m14.clou+mq+.com+19821+f+socr+r+1+R1Mw+sUMip+s+/+mp+
не могу понять почему так происходит
 
 
 
 
 
b707
Offline
Зарегистрирован: 26.05.2017

Вы, похоже, описание strtok вообще не читали - посмотрите, в чем смысл второго параметра. Это СПИСОК делителей для строки. Так нафига же вы туда передаете "SetBegin_" или "SetEnd_" ? - вот оно у вас и делит по каждому из встречающихся в вашем "делителе" символов.

fsdb
Offline
Зарегистрирован: 24.10.2015

если заменить на

for (char *p = strtok(sInput, "_"); p; p = strtok(NULL, "_")) {

то получаю:
SetBegin_router_777877787778_m14.cloudmqtt.com_19821_fdsocrnr_1ER1MwEsUMip_test/temp_SetEnd_
SetBegin+router+777877787778+m14.cloudmqtt.com+19821+fdsocrnr+1ER1MwEsUMip+test/temp+SetEnd+rя?ШX
правильно, выделяются, но
дальше по тексту выводит всякий мусор.

Serial.println(ssid);
Serial.println(pass);
Serial.println(mqtt_server);
Serial.println(mqtt_port);
Serial.println(mqtt_user);
Serial.println(mqtt_pass);
Serial.println(topic1);

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Это норма для данного кода.

fsdb
Offline
Зарегистрирован: 24.10.2015

надо как то из указателя вернуть текст и присвоить переменным. наверное.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А что Вы хотите получить-то? Задачу-то Вы не описали.

fsdb
Offline
Зарегистрирован: 24.10.2015

ЕвгенийП я бы хотел из перменной SerialBuff (String) получить разбивку на перменные char *ssid, *pass, *mqtt_server. сделать парсинг строки

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, Вы распишите где у Вас что. Вот Ваша строка

SetBegin_router_777877787778_m14.cloudmqtt.com_19821_fdsocrnr_1ER1MwEsUMip_test/temp_SetEnd_

Ну и где тут какая часть? Что является разделителем? народ ведь на кофейной гуще догадывается что Вам нужно.

fsdb
Offline
Зарегистрирован: 24.10.2015

Извинияюсь. Разделителем является нижнее подчеркивание. SetBegin_ маркер начала. SetEnd_ маркер конца. что данные целиком получены и могут быть использованы

fsdb
Offline
Зарегистрирован: 24.10.2015

наверное нужно было конкретно указать размер для переменных ? ssid ? и т.п.?

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

fsdb пишет:
то получаю: SetBegin_router_777877787778_m14.cloudmqtt.com_19821_fdsocrnr_1ER1MwEsUMip_test/temp_SetEnd_ SetBegin+router+777877787778+m14.cloudmqtt.com+19821+fdsocrnr+1ER1MwEsUMip+test/temp+SetEnd+rя?ШX правильно, выделяются, но дальше по тексту выводит всякий мусор.

А я так думаю, что просто это вам так кажется то, что вы туда подаёте ... а на самом деле после вашего SetEnd_ там нет завершающего '\0', и strtok() просто разгребает мусор вслед за тем, что вы считаете концом строки ... пока где-то случайно не встретит этот '\0'.

 

Olej
Olej аватар
Offline
Зарегистрирован: 05.03.2018

fsdb пишет:

    if (h1==0) {ssid=p;}
    if (h1==1) {pass=p;}
    if (h1==2) {mqtt_server=p;}
...

А вот таких присвоений вы просто не имеете права делать: p - это указатель, который при strtoc() пробегает последовательность начал токенов. Здесь должно быть копирование:

... strcpy( ssid, p );

Ну и, соответственно, всем этим ssid-ам должно быть предварительно создано (зарезервировано) место.

 

fsdb
Offline
Зарегистрирован: 24.10.2015

Olej, спасибо я догадывался в 4 посте, но не знал как.