3

I am pretty new to Arduino business. How do I read the last line from a SD Card? With following code snippet I can read the first line (all characters before "\n"). Now I would like to include a "backwards" statement (or something).

My code so far:

#include <SD.h>
#include <SPI.h>

File SD_File;

int pinCS = 10;

char cr;


void setup() {
  Serial.begin(9600);
  SD.begin();

  SD_File = SD.open("test.txt", FILE_WRITE);  
  SD_File.println("hello");
  SD_File.close();

  SD_File = SD.open("test.txt");
  while(true){
    cr = SD_File.read();
    if((cr == '\n') && ("LAST LINE?"))
        break;
    Serial.print(cr);
    }
  SD_File.close();

}

void loop() {

}

Your help is much appreciated.

Artur Müller Romanov
  • 4,417
  • 10
  • 73
  • 132
  • 1
    Your question is not clear. Are you looking for [`available()`](https://www.arduino.cc/en/Reference/FileAvailable) or [`peek()`](https://www.arduino.cc/en/Reference/FilePeek)? Note that last line does not necessarily end with `\n`. – zdf Jun 26 '18 at 13:12

2 Answers2

1

Since you are technically opening text files, you could use seekg to jump to the end of the file and read the last line, as described in this answer.

If this is not helpful, adding a bit more context and an example file would help us understand your question better.

Vlets
  • 61
  • 5
1

I am not sure I understood your question.

  • "How do I implement seekg?" There is not seekg. There is however, a seek.
  • This is the documentation page for the SD library. In the right side of the page there is a list of all File class methods (seek among others).
  • " How do I read the last line..." There is no line reading in your code. If you just want to go to the end of file use: SD_File.seek( SD_File.size() ); If you want to read the last line, the simplest way is to write a getline function and read the whole file line by line until end. Assuming MAX_LINE is large enough and getline returns zero on success:

//...
char s[ MAX_LINE ];
while ( getline( f, s, MAX_LINE , '\n' ) == 0 )
  ;

// when reaching this point, s contains the last line
Serial.print( "This is the last line: " );
Serial.print( s );

Here's a getline idea (no warranty - not tested):

/*
  s     - destination
  count - maximum number of characters to write to s, including the null terminator. If 
          the limit is reached, it returns -2.
  delim - delimiting character ('\n' in your case)

  returns:
     0 - no error
    -1 - eof reached
    -2 - full buffer
*/
int getline( File& f, char* s, int count, char delim )
{
  int ccount = 0;
  int result = 0;
  if ( 0 < count )
    while ( 1 )
    {
      char c = f.peek();
      if ( c == -1 )
      {
        f.read(); // extract
        result = -1;
        break;  // eof reached
      }
      else if ( c == delim )
      {
        f.read(); // extract
        ++ccount;
        break; // eol reached
      }
      else if ( --count <= 0 )
      {
        result = -2;
        break; // end of buffer reached
      }
      else
      {
        f.read(); // extract
        *s++ = c;
        ++ccount;
      }
    }

  *s = '\0'; // end of string
  return ccount == 0 ? -1 : result;
}
zdf
  • 4,382
  • 3
  • 18
  • 29