I'm quite new at programming C/Arduino, so this might be a really dumb/easy to solve question. 
I'm trying to read a directory using SdFat and store all filesnames in an array. I used to use the String object, but that took up too much SRAM, so now I'm trying the same with a more simple, yet difficult array of chars.
// Constants.
const uint8_t MAX_FILES = 100;
const uint8_t MAX_FILENAME_LENGTH = 20;
// Global vars.
uint8_t fileCount = 0;
char* filesLoaded[MAX_FILES];
/**
* Open the directory and add all files to an array.
*/
void openDir() {
 SdFile entry;
 char filename[MAX_FILENAME_LENGTH + 1]; // Add room for the 0-terminator.
 SD.chdir("/TESTFI~1", true); // @todo: hardcoded dir.
 SD.vwd()->rewind();
 fileCount = 0;
 while (fileCount <= MAX_FILES && entry.openNext(SD.vwd(), O_READ)) {
  entry.getFilename(filename);
  filename[MAX_FILENAME_LENGTH] = '\0';
  filesLoaded[fileCount++] = filename;
  entry.close();
 }
}
But when I print a file, all I get is garble.
Serial.println(filesLoaded[0]); // Output: 6����
What am I doing wrong? I've tried a number of things, but it's mostly guessing, trying, guessing and so on.
-tnx!-
The declaration
char* filesLoaded[MAX_FILES]
is allocating enough space for a list of pointers to character (arrays). There is no storage space allocated for the arrays.
This
 char filename[MAX_FILENAME_LENGTH + 1]; // Add room for the 0-terminator.
allocated the storage in your function, but the scope of the variable is only in the function. The array 'disappears' once you exit the function and the pointer that you have saved will be pointing to memory that is probably being reused by something else, as it is on the memory stack.
You need to change the first declaration to
char filesLoaded[MAX_FILES][MAX_FILENAME_LENGTH]
then use filesloaded instead of your filename variable in the function.
marco_c:
The declaration
char* filesLoaded[MAX_FILES]
is allocating enough space for a list of pointers to character (arrays). There is no storage space allocated for the arrays.
This
char filename[MAX_FILENAME_LENGTH + 1]; // Add room for the 0-terminator.
allocated the storage in your function, but the scope of the variable is only in the function. The array 'disappears' once you exit the function and the pointer that you have saved will be pointing to memory that is probably being reused by something else, as it is on the memory stack.
You need to change the first declaration to
char filesLoaded[MAX_FILES][MAX_FILENAME_LENGTH]
then use filesloaded instead of your filename variable in the function.
but, he could not actually use it, MAX_FILESMAX_FILENAME_LENGTH = 10020 = 2000 bytes.
The UNO has 2k of RAM but other things need ram too!
chuck.
You are right, I had not checked what MAX_FILES was!
As I told you already; I'm new at this 
I also tried to create an array of file index numbers, but SdFat (the 8.3 filename version) does not seem to have such a feature. The long filename SdFat has, but the VS1053 library I want to use to play audio only supports 8.3 filenames.
I'll have another look into creating that array of indexes and a function to get a filename based on that index as it will save me a lot of memory.
Sorting the index array according to the filenames will be another challenge 
Tnx!
You can save the list of file names to a text file and then read that a line at a time to process the files. I did something similar to read the names of midi files in order to allow the user to select the file to play next. You can find that code in the arduino library repository, link below in my signature block.
That, my good sir, is a very good idea!
It also fixes my need for a "sorting mechanism" as I can just use the sequence in the file!
I've written some code today that writes all files in a directory to INDEX.TXT and I'm trying to get the N'th line from that file.
I've found some example code to return an array of char here: Returning a C string from a function - Stack Overflow
INDEX.TXT:
2OBEYW~1.wav
3PILED~1.wav
4CONQU~1.wav
5TARHU~1.wav
1VAULT~1.wav
7GILGA~1.wav
8REVOL~1.wav
6VOIDW~1.wav
Function that fetches the N'th line:
// Files.
const uint8_t MAX_FILENAME_LENGTH = 13;
const char INDEX_FILENAME[] = "INDEX.TXT";
/**
* Get the N'th filename from the index.
*/
void getFilename(uint8_t index, char* filename) {
 char line[MAX_FILENAME_LENGTH];
 SD.chdir("/TESTFI~1", true); // @todo: hardcoded dir.
 // Open index file for reading.
 SdFile file(INDEX_FILENAME, O_READ);
 // Check for open error; create the missing file and try again!
 if (!file.isOpen()) {
  createIndexFile();
  SdFile file(INDEX_FILENAME, O_READ);
  if (!file.isOpen()) {
   error("Can't create index file.");
  }
 }
 // Read lines from the file.
 uint8_t n = 0;
 bool found = false;
 while ((file.fgets(line, sizeof(line) + 1)) > 0) {
  Serial.print(n);
  Serial.print(F(": "));
  Serial.print(line); // @todo: has a \n at the end?
  if (n == index) {
   strncpy(filename, line, MAX_FILENAME_LENGTH);
   filename[MAX_FILENAME_LENGTH] = '\0'; // Make sure the filename ends with a terminating zero.
   found = true;
   break;
  }
  n++;
 }
 file.close();
 // @todo: handle error!
 if (!found) {
  error("Requested index not found.");
 }
}
This works, kinda, but it has garbled data on the end of the string.
void updateDisplayFiles() {
 char filename[MAX_FILENAME_LENGTH];
 getFilename(0, filename);
 Serial.println(filename);
 getFilename(1, filename);
 Serial.println(filename);
}
Output:
0 - 2OBEYW~1.wav
2OBEYW~1.wav*
0: 2OBEYW~1.wav
1: 3PILED~1.wav
3PILED~1.wav*
I can't get rid of the *. What am I doing wrong? Is it the new line character (\n)?
A string declaration of length LENGTH has array indices 0 to LENGTH-1. Where are you putting the terminating null character?
Ah crap. Zero indexes ... well, I'll be heading off to bed now 
Tnx!