-1

I was wondering if anyone knew how to read in a random string from a file named "PhraseList.csv" or "PhraseList.xlsx" (whatever is easier)? There is a list of 10k.

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

File myFile;

void setup()
{

 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // re-open the file for reading:
  myFile = SD.open("PhraseList.xlsx");
  if (myFile) {
    Serial.println("PhraseList.xlsx":);

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening Phrase List");
  }
}

void loop()
{
    // nothing happens after setup
}
New contributor
Corey is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
0

Reading an individual string from a list in a file is not a simple operation. Well, it's "simple", but takes a lot of work.

It's not possible to say "Get me line number 2984 from the file" with a normal text file. You, instead, have to get each line in turn, discarding the ones you don't want, until you get to line 2984.

A better way would be to create custom "indexed" file format with a file header structure describing the rest of the file. That header structure would contain (amongst other possible things) the offset within the file of each string it contains.

For example you may choose to have the simplest arrangement - a list of 32 bit integers (4 bytes each), each one a simple offset from the start of the file for the string that corresponds to the same number, and have the strings NULL terminated in the file.

Such as:

00000000: 0c000000 17000000 22000000 53747269  ........"...Stri
00000010: 6e67206f 6e650053 7472696e 67207477  ng one.String tw
00000020: 6f005374 72696e67 20746872 656500    o.String three.

The idea with this now is you can seek in the file to "String no * 4" and read 4 bytes as an unsigned long (arranged little endian, like the Arduino uses), then use that value to do another seek. From there you can read bytes until you hit \0, at which point you know you have finished the string.

In the example above the string "String one" is located at offset 12 within the file. That's 0x0C in hexadecimal, or 0x0c 0x00 0x00 0x00 as a little-endian 32-bit integer. That's the first 4 bytes in the file. So you read those, interpret them as a 32-bit integer (12), then seek to that location in the file to get your string.

void readString(int num) {
    // Seek to the index entry
    myFile.seek(num * 4);

    // Read the index entry
    unsigned long offset = 0;
    myFile.read(&offset, 4);

    // You might want to add some sanity checking here

    // Seek to where the index points to
    myFile.seek(offset);

    // Read each character until you get a NULL.
    char c = myFile.read();
    while (c > 0) {
        Serial.write(c);
        c = myFile.read();
    }
    Serial.println();
}

Your Answer

Corey is a new contributor. Be nice, and check out our Code of Conduct.

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.