FileData чтение файла в массивы

kit

✩✩✩✩✩✩✩
19 Янв 2024
3
0
День добрый подскажите пожалуйста как реализовать данную задачу.
Имеем во внутренней фс littlefs некий файл file.csv со следующим содержанием:
111.222;222.222
111.333;222.333
111.444;222.444
111.555;222.444
Как мне считать из фс этот файл в программу и разложить содержимое в два массива:
float 1mass[] = {111.222,111.333,111.444,111.555};
float 2mass[] = {222.222,222.333,222.444,222.444};
Т.е. в первый массив складываются числа из первого столбца. Во второй из второго столбца.
Причем размер столбцов в файле при каждом считывании может меняться.
 

Сотнег

★★★★★★★
15 Янв 2020
4,654
1,573
@kit,
думаю, вы неправильно ставите себе задачу.
Логичнее изначально сохранить данные в формате, не требующем парсинга текстовых строк.
 

kit

✩✩✩✩✩✩✩
19 Янв 2024
3
0
К сожалению в программу придётся передавать файлы заранее подготовленные на компе в Excel
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,360
1,332
Москва
Первое, что надо понять: в подготовленном файле нет чисел - все текст. Т.е. Это все строки, можно использовать тип String, можно массив char, но первый все же поудобнее будет.
Далее надо научиться считывать файл построчно и сделать вывод в тот же монитор порта вместе со счетчиком индекса массива, т.е. получить что то типа:
Код:
0 111.222;222.222
1 111.333;222.333
2 111.444;222.444
3 111.555;222.444
Это уже часть дела - номер индекса по которому нужно разместить данные в массиве уже есть.
Далее надо работать с каждой отдельно взятой строкой.
Надо найти разделитель и вырезать часть строки с начала до разделителя , перевести во флоат и разместить в 1-ом массиве.
Из остатка строки удалить все с начала и до позиции разделителя, включая его. Остаток поместить во 2-ой массив.

А можно сделать чуть интереснее. Есть такая функция
readStringUntil()
Можно ее использовать для чтения нужных частей строки из файла. 1-ая будет читать до разделителя, вторая до конца строки.
 
  • Лойс +1
Реакции: Serg13

Старик Похабыч

★★★★★★★
14 Авг 2019
4,360
1,332
Москва
@kit, Не тупой, а альтернативно одаренный!
Примеры решают все проблемы. А на esp куча примеров записи и чтения файлов. Простейший есть в самой ардуино иде в разделе по LittleFS
 

Serg13

✩✩✩✩✩✩✩
20 Фев 2026
2
0
А можно сделать чуть интереснее. Есть такая функция
readStringUntil()
Можно ее использовать для чтения нужных частей строки из файла. 1-ая будет читать до разделителя, вторая до конца строки.
Благодарю за совет!
Вот такой пример получился :
C++:
// Arduino IDE 1.8.19. ESP32-C3. Используемая библиотека: LittleFS.h
// Чтение данных из файла с разделителем.
//  Закачиваем в корень LittleFS файл "test.txt".
//  Пример содержимого файла (4 строки) "test.txt":
//    Privet
//    Привет
//    125 526
//    Vsem privet!
//

#include "FS.h"
#include <LittleFS.h>
 
void setup() {
 
  Serial.begin(115200);
  delay(2000);
 
    if (!LittleFS.begin()) {
    Serial.println("Произошла ошибка при монтировании LittleFS");
    return;
  }
    
    File file = LittleFS.open("/test.txt", "r");
 
  if (!file) {
    Serial.printf("Не удалось открыть файл \"%s\" для чтения\n", file.name());
    return;
  }
  else {
    Serial.printf("\nРазмер файла \"%s\": %u байт;\n", file.name(), file.size());
 
    int line_count = 0;
    while (file.available()) {
      String line = file.readStringUntil('\n'); // Чтение строки до символа разделителя (здесь - символ новой строки)
      line_count++;
          //if (line_count == 3) // если нужна конкретная строка
          Serial.printf("Line %d: %s \n", line_count, line);
    }
  }
    file.close();
}
 
void loop() {
}
 

Serg13

✩✩✩✩✩✩✩
20 Фев 2026
2
0
@kit,
Понятно, что ТС вероятно забыл про эту тему, но для изучения перспективной файловой системы (ФС) LittleFS, пример довольно интересный. Приведу возможное решение (хотя для больших файлов *.csv, возможно, вместо массивов лучше создать отдельные файлы в ФС с аналогичным наполнением).

C++:
// Arduino IDE 1.8.19. ESP32C3 Dev Module. LittleFS.h
 
// Чтение данных из файла с различными разделителями.
//  Закачиваем в корень LittleFS файл "file.csv".
//  Пример содержимого файла (4 строки) "file.csv":
//    111.222;222.222
//    111.333;222.333
//    111.444;222.444
//    111.555;222.444
//  Помещаем левый столбец в массив 1; правый - в массив 2
 
#include "FS.h"
#include <LittleFS.h>
 
void setup() {
 
  Serial.begin(115200);
  delay(3000); // в некоторых случаях инициализация Serial требует дополнительного времени
 
    if (!LittleFS.begin()) {
      Serial.println("Ошибка инициализации LittleFS");
      return ;
    }
 
    File file = LittleFS.open("/file.csv", "r");
    if (!file) {
      Serial.printf("Не удалось открыть файл \"%s\" \n", file.name());
      return;
    }
 
    // Serial.printf("\nРазмер файла \"%s\": %u байт;\n", file.name(), file.size());
    // Если файл слишком большой, можно сообщить об этом
 
    // Определяем размер создаваемых массивов
    int index_count = 0;
    String lineIndex;
    while (file.available()) {
      lineIndex = file.readStringUntil('\n');
      if (lineIndex.length() > 0) index_count++; //количество не нулевых строк в файле (размер создаваемых массивов)
      }
    
    file.seek(0, SeekSet); // возвращаем указатель в начало файла
    
    float mass_1[index_count]; // объявляем массив 1
    float mass_2[index_count]; // объявляем массив 2
    
    int line_count = 0; //номер считываемой строки в файле (и индекс массивов)
    while (file.available()) {
      String line = file.readStringUntil(';');  // Чтение строки до символа разделителя - ;
      if (line.length() > 0) {          // если строка не нулевая
        Serial.println(line);           // для отладки
      float fl_line = line.toFloat();   // преобразовываем String в float
      mass_1[line_count] = fl_line;     // Преобразованную line помещаем в массив mass_1 с индексом = line_count
      
      String line2 = file.readStringUntil('\n'); // Продолжение чтения строки до символа разделителя \n (новой строки)
        Serial.println(line2);          // для отладки
      float fl_line2 = line2.toFloat(); // преобразовываем String в float
      mass_2[line_count] = fl_line2;    // Преобразованную line2 помещаем в массив mass_2
      line_count++;
      }
    }
 
    // Вывод массива 1 в последовательный порт (для отладки)
        Serial.println("");
        Serial.println("Массив 1:");
    for (int i = 0; i < line_count; i++) {
        Serial.println(mass_1[i], 3);   // выводим с точностью 3 знака после запятой
    }
      
    // Вывод массива 2
        Serial.println("");
        Serial.println("Массив 2:");
    for (int i = 0; i < line_count; i++) {
        Serial.println(mass_2[i], 3);   
 
  }
    file.close();
}
 
void loop() {
}