Странности string

Тема в разделе "Arduino & Shields", создана пользователем r0c, 18 мар 2021.

  1. r0c

    r0c Гик

    Код (C++):

    String ReadStringEEPROM (int Adr)
    {
      char* buf = new char[28]; //указатель на буфер
      for (byte i = 0; i < 27; i++)  //чтение еепром
      {
        buf[i] =  char(EEPROM.read(i + Adr));
        Serial.print(buf [i]);//вывод буфера побайтно 27 ед - выводится корректно
      }
      Serial.println(buf) ;//вывод буфера целиком 27 ед- здесь выводится мусор
      return String(buf).substring(0, 27);// в итоге возвращается мусор
    }
    Что можно сделать? Подскажите , пожалуйста
     
    собственно такая проблема. Arduino Mega.
    Иногда строка выводится корректно, иногда там мусор, иногда строка + мусор.
    Помогает перезагрузка, иногда только переподключение питания (внешнее +5 Вольт).
    1111122121199+9111-111-1122вывод буфера побайтно 27 ед
    1111122121199+9111-111-1122⸮⸮m⸮gM⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮m⸮n⸮G⸮⸮W⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ӛu⸮⸮z⸮⸮⸮⸮}⸮O۟⸮c|/⸮⸮⸮⸮⸮߾⸮⸮⸮⸮⸮_⸮=⸮⸮⸮O=⸮⸮⸮ߟ⸮nf⸮⸮⸮۝53?ͥ⸮⸮}⸮⸮⸮⸮⸮⸮Ϗ.w⸮⸮⸮\⸮ߤ⸮⸮r⸮⸮⸮⸮⸮c⸮:⸮5⸮⸮⸮ ⸮t⸮⸮⸮⸮4⸮Kpw⸮⸮+郎⸮⸮⸮?⸮N[⸮/⸮⸮᧏c.O-⸮⸮⸮-1_⸮⸮sv⸮⸮ɝ0y⸮jgގ⸮7⸮⸮_⸮⸮{⸮_⸮⸮⸮⸮⸮⸮|9⸮+v⸮V⸮:}⸮1⸮[⸮뾜޶⸮
    вывод буфера целиком 27 ед
     
  2. akl

    akl Гуру

    после заполнения буфера в последнюю ячейку надо записать ноль
    buf [27]=0;
     
    r0c, Andrey12 и SergeiL нравится это.
  3. ZAZ-965

    ZAZ-965 Гуру

    Попробуйте так
    Код (C++):
    char* buf = new char[28] (); //указатель на буфер
     
    r0c нравится это.
  4. r0c

    r0c Гик

    Спасибо за ответы! можно немного подробнее, для каждого случая?
     
  5. akl

    akl Гуру

    Serial.print при выводе символьного массива должен каким-то образом узнать что массив закончился. общепринятый в си способ - так называемая "нуль-терминированная строка"
     
  6. b707

    b707 Гуру

    для какого "каждого"?
    Просто запомните - признаком конца строки в Си является '\0'
     
  7. r0c

    r0c Гик

    buf [27]=0; и new char[28] ()
    я про это.
    Serial.println(buf) вводился лишь для отладки. был не понятно, почему не было возврата строки
     
    Последнее редактирование: 18 мар 2021
  8. b707

    b707 Гуру

    я не понимаю, о чем вы спрашиваете
    возврат строки и терминальный ноль в массиве char[] не имеют никакого отношения друг к другу
     
  9. Igor68

    Igor68 Гуру

    А так:
    Код (C++):
    String ReadStringEEPROM (int Adr)
    {
      char* buf = new char[28]; //указатель на буфер
      for (byte i = 0; i < 27; i++)  //чтение еепром
      {
        buf[i] =  char(EEPROM.read(i + Adr));
        Serial.print(buf [i]);//вывод буфера побайтно 27 ед - выводится корректно
      }
      buf[27] = '\0';
      Serial.println(buf) ;//вывод буфера целиком 27 ед- здесь выводится мусор
      return String(buf).substring(0, 27);// в итоге возвращается мусор
    }
    работает?
    По моему ребята говорят про конец строки

    Тут проскочила мысль и про 0x0D и 0x0A... вот только не помню кто из них кто... но '\n' как я привык конец.
    Со string вообще не люблю сталкиваться (был случай когда он пробел 0x20 принимал за конец хоть и не строки, но слова имя параметра):confused:

    И вообще тут то buf[xx], то *buf применяется... Вы уж определитесь в конце концов.
     
    Последнее редактирование: 18 мар 2021
  10. AlexU

    AlexU Гуру

    Не надо использовать:
    Код (C++):
    char* buf = new char[28];
    смысла нет ни какого. И есть проблема в том, что выделенная память не освобождается.
    Достаточно:
    Код (C++):
    char buf[28];
    Такой буфер будет удалён после выхода из функции.
     
    r0c нравится это.
  11. akl

    akl Гуру

    0x0D это '\r', а 0x0A это '\n'
    но кстати да, динамический массив если он не удаляется может наделать делов.
     
  12. r0c

    r0c Гик

    Все предложенные решения помогают. Всем спасибо за помощь!