Разделить строку на слова

Joiner
Offline
Зарегистрирован: 04.09.2014

Сделал отдельный Datalogger на отдельной платке. Нафига? А потому что хронически не хватало пинов после подключения SD карты и LCD монитора. Теперь такой проблемы нет. Теперь основная плата через TX отдает данные в виде строки на Datalogger. Daalogger их принимает и пишет на SD карту, и на всякий случай отправляет (если логгер запитан от USB компа) эту строку на комп, что позволяет наблюдать за процессом на компе (если надо) или обрабатывать данные.  И  плюс к тому к логгеру можно подключить LCD мониторчик и любоваться процессом через него.

 Все это я реализовал, кроме вывода на дисплей. Строка довольно длинная...примерно такая -

"1238 123.45 12.28 1034 132.45 0.328 14.77 66.34 0.884". Первая цифра до первого пробела это номер записи, остальные цифры, разделенные пробелами данные по каналам.

  Мечтаю эту огромную строку как-то разделить и выводить на LCD частями по каналам, перелистывать кнопочкой.

  Подскажите плиз, куда копать. Два дня изучаю String и прочие действия...пока ни чего не получается

  Да..забыл сказать... Я - чайник

Спасибо

inspiritus
Offline
Зарегистрирован: 17.12.2012

Как то предпоследняя строка не вяжется со всеми предыдущими, или Вы радикально самокритичны ;)

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо....воспринял как комплимент :)

Но веь не могу пока со строкой справиться :(

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Можно в сторону регулярных выражений посмотреть

А можно в сторону strtok

Ulitos
Offline
Зарегистрирован: 10.02.2015

Примените strtok. Проверенная временем надежная штука

Joiner
Offline
Зарегистрирован: 04.09.2014

Penni пишет:

Можно в сторону регулярных выражений посмотреть

А можно в сторону strtok

А что такое strtok?  Напишите пожалуйста строчку для примера.

Я такого слова не встречал. Что оно делает?

Я пока смог посчитать кол-во символов в строке и кол-во слов. Что дальше пока не знаю.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015
char str[] ="1238 123.45 12.28 1034 132.45 0.328 14.77 66.34 0.884";
char * pch;
pch = strtok (str," ");
while (pch != NULL)
{
  Serial.println(pch);
  pch = strtok (NULL, " ");
}

 

Joiner
Offline
Зарегистрирован: 04.09.2014

Penni, спасибо. Сейчас буду пробовать

 

ООО! Что-то получилось! Выводит на монитор порта отдельными словами.

Правда пока не понял как это работает. Буду разбираться, пытаться понять.

Огромное спасибо тем, кто откликнулся!

Joiner
Offline
Зарегистрирован: 04.09.2014
char str[] ="1238 123.45 12.28 1034 132.45 0.328 14.77 66.34 0.884"; 

char * pch; //Что это такое и что оно делает???
pch = strtok (str," "); //Это так понимаю оператор strtok и здесь
                        //он отделяет первое слово
while (pch != NULL) //Здесь, как понимаю начинается цикл
{ 
  Serial.println(pch); // Здесь выводим первое и последующие слова
  pch = strtok (NULL, " ");//Здесь, как понимаю извлекаем следующее слово
} 
//А дальше, когда вывелось первое слово и все последующие, в
//в цикле печатается первое слово. Не понимаю почему именно первое

Вынужден обратиться снова. Перелопатил интернет, но так и не понял полностью работу этой программы. Особенно не понятна строка char*pch

Подскажите пожалуйста.

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

strtok возвращает указатель на последнюю найденную лексему в строке. Возвращается пустой указатель, если нет найденных лексем. (это из описания функции) для этого и нужна переменная pch которая является указателем на тип чар. Остальное всё так и есть как в комментариях. Если Вы этот код в loop запихаете, то в терминал будут без остановки валиться слова.

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо.

Но что-то все равно не понял строку char*pch . Так понимаю, что pch - имя переменной, а char - это тип переменной. А что там за звездочка? Просмотрел весь справочник по программированию ардуино и там такого не нашел.

А про "будут валиться слова" мне понятно, что если в цикле loop, но непонятно почему валится бесконечно только первое слово

1238

123.45

12.28

1034

132.45

0.328

14.77

66.34

0.884 Это последнее слово в строк

1238 Откуда снова появляется первое слово и выводится бесконечно

1238

1238

........и так далее

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

* это указатель, в данном случае указатель на тип char. Т.е. pch это указатель, он хранит не само значение, а адрес в памяти (указатель на кусок памяти) где лежит нужное значение.

https://ru.wikipedia.org/wiki/%D3%EA%E0%E7%E0%F2%E5%EB%FC_(%F2%E8%EF_%E4%E0%ED%ED%FB%F5)

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо, Penni. Пока правил свой вопрос, Вы уже ответили. А мне еще немного непонятно с первым словом. Спасибо за ссылочку, пойду грызть гранит науки :)

Спасибо.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Не знаю. У меня все слова сыпятся, а не только первое.

Joiner
Offline
Зарегистрирован: 04.09.2014
char str[] ="1238 123.45 12.28 1034 132.45 0.328 14.77 66.34 0.884";
void setup(){
  Serial.begin(9600);
}

void loop(){
char * pch;
pch = strtok (str," ");
while (pch != NULL)
{
  Serial.println(pch);
  pch = strtok (NULL, " ");
delay(1000);
 }
}

У меня вот так написано. И после вывода всех слов продолжается вывод первого.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

потому что str объявлена как глобальная переменная, а strtok при работе изменяет "строку" т.е. она на место разделителей (в нашем случае пробел) ставит символ конца строки, тем самым мы имеем возможность по указателю pch считать только искомую лексему. Поэтому для второго и последующего вызова loop переменная str будет 1238

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо. Понял.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

http://lord-n.narod.ru/download/books/walla/programming/Spr_po_C/main.ht...

глава 14 про strtok (NULL, " ");  и остальных её друзей

Joiner
Offline
Зарегистрирован: 04.09.2014

SU-27-16, спасибо за ссылочку!

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Joiner пишет:

SU-27-16, спасибо за ссылочку!

не за что.....  её я получил от Penni - ему спасибо :)

Joiner
Offline
Зарегистрирован: 04.09.2014

И Penni большое спасибо :) Хороший справочник.

Snubist
Offline
Зарегистрирован: 18.02.2013

Рекомендую еще сразу почитать книгу по языку С, того же Страуструпа для начала.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Snubist пишет:

Рекомендую еще сразу почитать книгу по языку С, того же Страуструпа для начала.

О да! У него просто отличные книги во всех изданиях. Читать о языке в книге, написанной самим разработчиком великолепно! И пишет отлично, читается легко, и понимание приходит сразу. У меня вот стоит на полочке издание от 1991 года :) Еще со времен школы осталось.

Joiner
Offline
Зарегистрирован: 04.09.2014

Спасибо, ребята! Книгу поищу и почитаю

Спасибо

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Ребят, здорово, не могу понять логику кода, как из этой функции получить Мой_Метод(){/**/}, который бы брал бы на входе:
(String InputString, String delimiter) и возвращал бы: скажем, 5-й элемент после разбивки. У меня ни ф..а не получается.

void setup() {
Serial.begin(9600);          
char str[] ="124;1;10;100;104";
char * pch;
pch = strtok (str,";");
while (pch != NULL)
{
  Serial.println(pch);
  pch = strtok (NULL, ";");
}
}
void loop() {
}

 

 
brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ты понимаешь отличие String vs char[] ?

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Не понимаю как работает PIN UP ddd

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Не понимаю как привести *char к String?
 

ddr2
Offline
Зарегистрирован: 27.12.2020
Зачем здесь NULL ? ( 9 - строка)
 
  pch = strtok (NULL";");
 
ddr2
Offline
Зарегистрирован: 27.12.2020
char str[] ="124;1;10;100;104";
char * pch = str;

while(1) {
   pch = strtok (pch, ";");
   if (pch == NULL) break;
   printf("%s\n", pch);
} 

 

countervectorbase
Offline
Зарегистрирован: 04.10.2020

Как привести char* к String [мне это нужно очень];    ? 

ddr2
Offline
Зарегистрирован: 27.12.2020

не знаю, наверное

char c_str[] = "aaaaaaaaa";
std::string cpp_str(c_str);

 

countervectorbase
Offline
Зарегистрирован: 04.10.2020

void setup() {
String S0=0;
Serial.begin(9600);          
char str[] ="124;1;10;100;104";
char * pch;
pch = strtok (str,";");
while (pch != NULL)
{
  Serial.println(pch);
  pch = strtok (NULL, ";");
}
}
void loop() {
}

Не понял. У меня есть переменная String S0, и есть char * pch; Вопрос: как мне грамотно присвоить в S0 значение той самой char * pch? Чтобы было так S0 = pch; Как???
Ddr2, как Вы со мной?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Никак. String это класс, а char* - указатель на массив. А вот это "S0 = pch" ваще бред, прям адский бред :)

Если есть желание работать с классом String, то работайте с ним его методами https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/

А если хочешь использовать массив чаров, то используйте strok strcmp strcpy и прочее.

Ну и на всякий случай, если суржик - ваше все смотри String.c_str() . Ну а вообще ... Че в гугле забанили ? 

Эти вопросы для песочницы.