Операции Strtok на Arduino Zero, похоже, не работают во время выполнения

Я пытаюсь протестировать функциональность strtok() на новом оборудовании, так как мне не хватило памяти для разработки на моем Nano. Это базовый пример из Интернета, включающий токенизацию строки и передачу токенизированных записей через SerialUSB. Я использую Rocketscream V3 (Arduino Zero ATSAMD21G18A).

#include <string.h>

void setup() {
  char *token;
  char *mystring = "apples,pears,bananas";

  SerialUSB.begin(9600);
  while (!SerialUSB) { }

  SerialUSB.print("Serial established");

  token = strtok(mystring, ",");
  
  while (token != NULL) {
    SerialUSB.println(token);
    token=strtok(NULL, ",");
  }
}

Код работает, как и ожидалось, на моем Nano (с Serial вместо SerialUSB), но хотя он и компилируется для Arduino Zero, Zero никогда не выходит за пределы печати «Serial установлен». Я подтвердил это, включив код (последовательная печать, мигание светодиода) после частей токенизации, и они никогда не выполняются. Функция цикла() никогда не достигается, кажется, что она останавливается на "token = strtok(mystring, ",");".

Я не могу придумать более простой способ протестировать strtok(), но он просто не работает. Любая помощь будет оценена по достоинству.

, 👍2


1 ответ


1

strtok работает путем изменения исходной строки. Ваша тестовая строка указывает на константную строку.

  char *mystring = "apples,pears,bananas";

Эта конкретная платформа может поместить это в постоянную память. Попробуйте вместо этого использовать тестовую строку:

  char mystring [] = "apples,pears,bananas";

У меня нет нуля для тестирования, но в любом случае использование strtok в константной строке не рекомендуется запрещено.


Если вы включите предупреждения для компилятора (Файл -> Настройки), вы увидите следующее:

 In function 'void setup()':
 warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   char *mystring = "apples,pears,bananas";

Если вы делаете что-то "запрещенное" тогда не ждите хороших результатов.

,

Вы имеете в виду char mystring[] = "apple,pears,bananas";., @Edgar Bonet

О, и это намного хуже, чем «не рекомендуется». Это «[неопределённое поведение](https://www.nayuki.io/page/undefined-behavior-in-c-and-cplusplus-programs)»., @Edgar Bonet

Компилятор должен, по крайней мере, предупреждать, если не выдавать ошибку, за передачу константной строки в указатель на char., @Nick Gammon

А, так и есть, если включить предупреждения., @Nick Gammon

@EdgarBonet Да, небольшая опечатка. Зафиксированный., @Nick Gammon

Спасибо @Nick_Gammon, я не знал, что у меня отключены предупреждения. Это было все, что мне было нужно. Итак, написанный код имеет неопределенное поведение, но почему он успешно выполняется на Nano? Просто причуда того, как он обращается с памятью во время выполнения?, @Jacob Graber

Неопределённое поведение по определению будет вести себя неожиданным (или даже неопределённым) образом. Nano может не волновать, что вы записываете в постоянную память., @Nick Gammon