Кусать строку

Borv

✩✩✩✩✩✩✩
4 Фев 2021
23
1
Здравствуйте,

Нужно считать текстовый файл в 1 строку и потом "откусывать" от строки блоки (до символа "=", до символа "перехода строки \n") постепенно продвигаясь от 1 к последнему символу. Зачем? Так гораздо быстрее, чем ради каждого значения искать перебором по всему тексту.

Файл:
C++:
Setting1=100
Setting2=200
итд
Строка должна быть соответственно вида:
C++:
Setting1=100\nSetting2=200\nитд
"Откусывать" по шагу:
C++:
Удаляем первый кусман от 1 символа до включая символ "=" то есть [Setting1=];
Потом считываем и присваиваем значение от 1 символа до \n то есть [100], затем его тоже удаляем;
Мой кривой код. Как ни пишу, не работает. Замуты С++ с String/string()/char/char*/итп знаю плохо - может кто-то просто написать рабочий код, пожалуйста:
C++:
File configFile = SD.open("/tester.cfg", FILE_READ);
char configFile_data = configFile.read();
String configFile_data_str = String(configFile_data);
configFile_data_str.remove(0, length(configFile_data_str.readStringUntil("="))+1);
Setting1 = configFile_data_str.readStringUntil("\n");
configFile_data_str.remove(0, length(configFile_data_str.readStringUntil("\n"))+1);
 
Изменено:

Геннадий П

★★★★★★✩
14 Апр 2021
1,966
632
44
Разбейте задачу на подзадачи.
1) прочитать строку из файла - Arduino File.readString() | Arduino Reference (arduinogetstarted.com)
2) разбить строку на две - Split String in Arduino | Delft Stack
Не нужно все сразу делать. Научитесь сначала считывать построчно из файла, затем научитесь разбивать строку, и уже только потом совмещайте все вместе.
 

Borv

✩✩✩✩✩✩✩
4 Фев 2021
23
1
Вы не поняли суть решения.
Считывать построчно из файла - это плохо, тк многократные обращения к SD-card.
Также у Arduino нет понятия "курсор", поэтому "просто считать следующую строку" нельзя.
Для получения каждого следующего значения придётся перебирать весь предыдущий текст заново и заново.
Поэтому придумал такое решение - загоняем ВЕСЬ текстовый файл в строку в памяти за 1 чтение с SD-card, затем от этой строки откусываем спереди куски - то-есть без перебора уже использованного текста!
Пожалуйста, не нужно переделывать решение, просто подскажите верный код для данного решения!

Или в C++ [File.readString();] считывает за раз ВЕСЬ ФАЙЛ, а не 1 строку??? 🤦‍♂️ Тогда в чём разница с [File.read();]???
 
Изменено:

Геннадий П

★★★★★★✩
14 Апр 2021
1,966
632
44
@Borv, Ну, если вам так критично, то проделайте два раза операцию разделения:
Разделяете по "\n" - получаете массив строк
Затем разделяете каждую строку по "=" - получаете название-значение
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
464
134
@Borv,
Первое. При написании программы надо учитывать количество доступной памяти. Весь файл может просто не поместиться в память.
Второе. Считывание SD производится блоками. И если файл маленький, то он прочитается сразу весь в память и больше обращений к SD не будет.
Поэтому совет - сделайте сначала построчную обработку. Потом можете проверить сколько времени занимает поиск первой и последующих строк.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,966
632
44
Также у Arduino нет понятия "курсор", поэтому "просто считать следующую строку" нельзя.
А пример вы не смотрели по ссылке?
C++:
  file = SD.open("arduino.txt", FILE_READ);
  if (file) {
    if ( file.available()) {
      String data = file.readString();
      Serial.println(data);
    }

    file.close();
  } else {
    Serial.print(F("SD Card: error on opening file"));
  }
 

Borv

✩✩✩✩✩✩✩
4 Фев 2021
23
1
Про курсор - Не выдумывайте. Каждое следующее считывание продолжается с места, где закончилось предыдущее.
Офигеть, неужели, а где об этом сказано?!
А пример вы не смотрели по ссылке?
Из примера не ясно - считаны 2 строки по 1 * 2 раза или 2 строки за 1 проход включая символ "\n". :p В другой подобной теме про курсор никто не ответил, поэтому подумал, что курсора в Arduino просто нет.
Хорошо, что есть курсор. Но данную задачу это не решает.

Считывание SD производится блоками. И если файл маленький, то он прочитается сразу весь в память и больше обращений к SD не будет.Поэтому совет - сделайте сначала построчную обработку. Потом можете проверить сколько времени занимает поиск первой и последующих строк.
Зачем эти мучения, если лучший алгоритм уже описан в 1ом постинге?!
Массивы итп не помогают, тк переменные каждая по отдельности, каждой индивидуально нужно назначить значение, подстановки переменной для назначения значения в C++ недопустимы. Нафига тогда мучиться со всем этим?
Лучше всего просто как я написал вверху - считать весь текстовый файл в память и "покусать строку".
Кто таки может написать эти 2-3 строчки кода??
 

bort707

★★★★★★✩
21 Сен 2020
3,058
910
Массивы итп не помогают, тк переменные каждая по отдельности, каждой индивидуально нужно назначить значение
Так это же вопрос проектирования программы.
Почему переменные по отдельности? Что мешает организовать их в массив или структуру? Заодно, если правильно выбрать формат, можно вообще отказаться от парсинга строк и читать все в бинарном виде сразу в нужные структуры в программе.
 

Borv

✩✩✩✩✩✩✩
4 Фев 2021
23
1
Пара уточнений:
1) Для двухмерных массивов (таблиц) String array[][] есть ли встроенная функция поиска нужного значения по диапазону ячеек или по всей колонке или по всей строке? Вроде String.IndexOf(), но для массива? Чтобы много циклов не писать.
2) Два значения в String array[][] из текстового файла это SSID и Password для WiFi латинскими буквами и цифрами. По Serial.Print оба значения выводит верно. Но подключиться к WiFi не может. Если оба значения ввести в код программы вручную, то сразу подключается. Почему? Мб нужна какая-то перекодировка? Кодировка текстового файла их которого считываются значения UTF-8.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,058
910
1) Для двухмерных массивов (таблиц) String array[][] есть ли встроенная функция поиска нужного значения по диапазону ячеек или по всей колонке или по всей строке? Вроде String.IndexOf(), но для массива? Чтобы много циклов не писать.
нет
Если оба значения ввести в код программы вручную, то сразу подключается. Почему?
значит читаете из файла неправильно.
Выведите в консоль значения, прочтенные из файла и заданные вручную в программе. Только не в виде текста, а в HEX формате. Наверняка строки будут неравны.