Skip to content

РЕЗКАЯ КАК ПОНОС И ЛЁГКАЯ КАК ПЁРЫШКО ЗАМЕНА STRING

License

Notifications You must be signed in to change notification settings

GyverLibs/mString

Repository files navigation

latest PIO Foo Foo Foo

Foo

mString

РЕЗКАЯ КАК ПОНОС И ЛЁГКАЯ КАК ПЁРЫШКО ЗАМЕНА STRING

  • Практически полный аналог String, но статический
  • Дополнительные функции для Flash-строк
  • Есть несколько встроенных функций парсинга строк

Совместимость

Совместима со всеми Arduino платформами (используются Arduino-функции)

Содержание

Установка

  • Библиотеку можно найти по названию mString и установить через менеджер библиотек в:
    • Arduino IDE
    • Arduino IDE v2
    • PlatformIO
  • Скачать библиотеку .zip архивом для ручной установки:
    • Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
    • Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
    • Распаковать и положить в Документы/Arduino/libraries/
    • (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
  • Читай более подробную инструкцию по установке библиотек здесь

Обновление

  • Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
  • Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
  • Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!

Инициализация

Библиотека может работать в двух режимах:

  • Внутренний буфер (по умолчанию) - текстовый буфер создаётся внутри объекта mString<размер>
  • Внешний буфер - при создании объекта mString передаётся внешний char массив и его размер. Для включения режима внешнего буфера нужно объявить #define MS_EXTERNAL перед подключением библиотеки

Внутренний буфер

#include <mString.h>
// внутренний буфер
// размер в количестве символов
mString<размер> str;

Внешний буфер

mString(char* nbuf, uint16_t size, bool clear = true);
// nbuf - внешний char буфер
// size - его размер
// clear - очищать при инициализации

Пример:

#define MS_EXTERNAL
#include <mString.h>

// с очисткой для корректной инициализации памяти
char buf1[10];
mString str1(buf, 10);

// без очистки (строка "hello" останется)
char buf2[10] = "hello";
mString str2(buf2, 10, false);

Использование

// =========== СИСТЕМА ===========
uint16_t length();                                      // текущий размер (в кол-ве символов)
void updateLength();                                    // пересчитать длину (если строка меняется извне)
uint16_t capacity();                                    // максимальный размер (в кол-ве символов)
void clear();                                           // очистить

// ========= ПРИБАВЛЕНИЕ =========
void add( [char / char* / fstring / числа / String] );  // добавить (почти любой тип данных)
void add_P(PGM_P s);                                    // добавить строку из Flash
void add(char* str, uint16_t len);                      // добавить строку из буфера
void add(uint8_t* str, uint16_t len);                   // добавить строку из буфера

str += [char / char* / fstring / числа / String];       // добавить (почти любой тип данных)
str = str + [char / char* / fstring / числа / String];  // суммировать (почти любой тип данных)

// ========== СРАВНЕНИЕ ==========
bool equals(char* s);                       // совпадает со строкой
bool equals_P(PGM_P s);                     // совпадает со строкой из Flash

str == [char / char* / числа / String];     // сравнить (почти любой тип данных)

// ======= ДОСТУП К БУФЕРУ ========
// Чтение символа по индексу
str[idx];
str.buf[idx];
str.charAt(idx);

// Запись символа по индексу
str[idx] = с;
str.buf[idx] = с;
str.setCharAt(idx, c);

// Доступ к char буферу
char[] buf;
char* c_str();

// =========== ЭКСПОРТ ===========
int32_t toInt(from = 0);                // в 32 бит целое начиная с from
float toFloat(from = 0);                // в float начиная с from
void substring(from, to, char* arr);    // скопировать с from до to во внешний arr

// ======= ПРЕОБРАЗОВАНИЕ ========
void truncate(amount);          // обрезать с конца на amount
void remove(idx, amount);       // удалить (вырезать) amount символов начиная с idx

void toLowerCase();             // преобразовать буквы в нижний регистр (ASCII)
void toUpperCase();             // преобразовать буквы в верхний регистр (ASCII)

// ============ ПОИСК ============
int indexOf(char, from = 0);    // найти символ char, искать начиная с from
int indexOf(char*, from = 0);   // найти строку char, искать начиная с from

int lastIndexOf(char);          // найти последний символ char
int lastIndexOf(char, from);    // найти последний символ char, искать начиная с from

bool startsWith(char* s);       // начинается с
bool startsWith_P(PGM_P s);     // начинается со строки из Flash

bool endsWith(char *s);         // заканчивается на
bool endsWith_P(PGM_P s);       // заканчивается на строку из Flash

// ========= РАЗДЕЛЕНИЕ =========
int splitAmount(char div = ',');        // посчитать количество подстрок по разделителю
int split(char** str, char div = ',');  // разделить на строки по разделителю div
void unsplit(char div = ',');           // вернуть разделители после split

// ========== ПАРСИНГ ==========
// Парсинг пакета, в котором данные разделены разделителем div
// data - целочисленный массив любого типа
// bsize - вес типа массива (byte - 1, uint16_t - 2, long - 4)
// len - размер массива в количестве ячеек
// div - разделитель
int parse(void* data, uint8_t bsize, int len, char div = ',');

// устаревшие
int parseBytes(data, len, div); // распарсить содержимое в массив byte длиной len
int parseInts(data, len, div);  // распарсить содержимое в массив int длиной len

Пример

#include "mString.h"
void setup() {
  Serial.begin(9600);
  /*
    mString<50> str;
    str = "kek";
    str = str + ',' + 12345 + ',' + 3.14 + ',' + "hello";
    Serial.println(str.buf);
    str = 1234;
    Serial.println(str.toInt());
    // скетч занимает 2522/198 байт
  */
  /*
    // сравнение со String
    String str;
    str = "kek";
    str = str + ',' + 12345 + ',' + 3.14 + ',' + "hello";
    Serial.println(str);
    str = 1234;
    Serial.println(str.toInt());
    // скетч занимает 5370/208 байт
  */

  // прочие тесты
  mString<50> test;

  test = "puk ";
  test += "kek ";
  test = test + "cheburek" + ',' + 123 + ',' + 3.14;

  Serial.println(test.buf);   // puk kek cheburek,123,3.14
  test.clear();   // очистить
  //test = "";    // аналогично

  mString<10> some;
  some = "added ";
  String str = "String";
  test += some.buf;
  test += str;

  Serial.println(test.buf);   // added String

  // парсинг
  test = "1234,2345,-3456,4567,5,6";
  Serial.println(test.startsWith("lol2"));  // 0
  Serial.println(test.startsWith("1234"));  // 1
  Serial.println(test.indexOf('k'));    // -1

  int16_t data[10];
  int get = test.parse(data, 2, 10);   // 10 ячеек по 2 байта
  Serial.println(get);    // 6
  Serial.println();

  for (int i = 0; i < get; i++) {
    Serial.println(data[i]);   // 1234 2345 -3456 4567 5 6
  }

  // поиск
  test = "puk kek hello friend hello world";
  Serial.println(test.indexOf('h'));       // 8
  Serial.println(test.indexOf('h', 9));    // 21
  Serial.println(test.indexOf("friend"));  // 14

  // сравнение
  test = 12;
  Serial.println(test == 12);     // 1

  test = "kek";
  Serial.println(test == "kek");  // 1

  mString<40> test2;
  test2 = "kek";
  Serial.println(test == test2.buf);  // 1

  // выделение
  test = "abcd,123,-456,3.14";
  Serial.println(test.toInt(5));    // 123
  Serial.println(test.toInt(9));    // -456
  Serial.println(test.toFloat(14)); // 3.14

  char buf3[10];
  test.substring(0, 5, buf3);
  Serial.println(buf3);   // abcd,1

  test.remove(5, 4);
  Serial.println(test.buf);   // abcd,-456,3.14
  test.toUpperCase();
  Serial.println(test.buf);   // ABCD,-456,3.14
  test.truncate(4);
  Serial.println(test.buf);   // ABCD,-456,

  // разделение
  test = "hello,1234,test,5678";
  char* strings[test.splitAmount(',')];
  int amount = test.split(strings, ',');
  // действие испортит строку, добавив в неё NULLы!

  for (int i = 0; i < amount; i++) {
    Serial.println(strings[i]);
  }
  
  Serial.println(atoi(strings[1]));
  Serial.println(atof(strings[2]));
  
  // вернуть строку к исходному виду
  test.unsplit();
}

void loop() {
}

Версии

  • v1.0
  • v1.1 - разбил утилиты на .h .cpp
  • v1.1.1 - исправлена ошибка компиляции
  • v1.2
    • Исправлено прибавление uint32_t чисел
    • Добавлен режим внешнего буфера
    • Добавлены _P функции для строк из Flash
    • Добавлена unsplit()
  • v1.3 - добавлена универсальная функция parse
  • v1.4 - возможность инициализации внешнего буфера без очистки
  • v1.5 - добавлена updateLength()
  • v1.6 - исправлена ошибка на ESP32, добавлена splitAmount()
  • v1.7 - оптимизация скорости, добавлены add(uint8_t* str, uint16_t len), lastIndexOf и endsWith

Баги и обратная связь

При нахождении багов создавайте Issue, а лучше сразу пишите на почту [email protected]
Библиотека открыта для доработки и ваших Pull Request'ов!

При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:

  • Версия библиотеки
  • Какой используется МК
  • Версия SDK (для ESP)
  • Версия Arduino IDE
  • Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
  • Какой код загружался, какая работа от него ожидалась и как он работает в реальности
  • В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код

About

РЕЗКАЯ КАК ПОНОС И ЛЁГКАЯ КАК ПЁРЫШКО ЗАМЕНА STRING

Resources

License

Stars

Watchers

Forks

Packages

No packages published