Search code examples
fileesp32arduino-c++arduino-esp32

Reading line by line in Arduino IDE


I'm trying to read txt file (has numeric values) line by line. I used SPIFFS and I used this function

void readFile(fs::FS &fs, const char * path){
   Serial.printf("Reading file: %s\r\n", path);

   File file = fs.open(path);
   if(!file || file.isDirectory()){
       Serial.println("− failed to open file for reading");
       return;
   }
   
   int count = 0;
   Serial.println(" read from file:");

   while(file.available()){
    if (count < 100)  
      Serial.write(file.read());  
   } 
}

What is the alternative function for "file.read()" something like "readline" because I need to read the file from first line to 100 and from 101 to 200 and so on .


Solution

  • You need to use readStringUntil. Although it's not the most efficient way, i'll show you how it's done.

    #include <vector>
    #include <SPIFFS.h>
    
    std::vector<double> readLine(String path, uint16_t from, uint16_t to) {
      std::vector<double> list;
      if(from > to) return list;
      File file = SPIFFS.open(path.c_str());
      if(!file) return list;
      uint16_t counter = 0;
      while(file.available() && counter <= to) {
        counter++;
        if(counter < from) {
          file.readStringUntil('\n');
        } else {
          String data = file.readStringUntil('\n');
          list.push_back(data.toDouble());
        }
      }
      return list;
    }
    
    void setup() {
      Serial.begin(115200);
      SPIFFS.begin(true);
      
      std::vector<double> numbers = readLine("file.txt", 0, 100);
      Serial.println("Data from 0 to 100:");
      uint16_t counter = 0;
      for (auto& n : numbers) {
        counter++;
        Serial.print(String(n) + "\t");
        if(counter % 10 == 0) {
          Serial.println();
        }
      }
    
      numbers = readLine("file.txt", 101, 200);
      Serial.println("\nData from 101 to 200:");
      counter = 0;
      for (auto& n : numbers) {
        counter++;
        Serial.print(String(n) + "\t");
        if(counter % 10 == 0) {
          Serial.println();
        }
      }
    }
    

    UPDATE

    Supposed you have 1050 values and you want to parse it for each 100 values.

    int i = 0;
    while(i < 1050) {
      int start = i + 1;
      int end = (i + 100) > 1050 ? 1050 : i + 100;
      std::vector<double> numbers = readLine("file.txt", start, end);
      
      Serial.println("Data from " + String(start) + " to " + String(end) + ":");
      uint16_t counter = 0;
      for (auto& n : numbers) {
        counter++;
        Serial.print(String(n) + "\t");
        if(counter % 10 == 0) {
          Serial.println();
        }
      }
    
      i += 100;
    }