SDFat Store Root Directory File Names in Array

Hi. I’m trying to store the files with a “.HEX” extension on the root of an SD to an array called directory using the function below (SDFat Library). Now when I do a serial print of the file names, I get three files, for example a.hex, b.hex and c.hex. Now I save the same files to a directory char* array, and increment a counter for the position where I save the files. However when I read back from the directory array, I get an output of c.hex, c.hex, c.hex. What is happening? I’ve tried moving all the code around but am just not able to figure out why its behaving so strangely. Any help would be appreciated. Thanks!

P.S. The SDFat library initialises and works perfectly in all other cases.

char* directory[][50] = {"Files on Card"};
int fileCounter = 0;

void showDirectoryLCD ()
  {
    
  if (!haveSDcard)
    {
    Serial.println (F("*** No SD card detected."));
    lcd.clear();
    lcd.print("No SD Card");
    delay(1000);
    return;
    }
    
  // list files in root directory
  fileCounter = 0;
  SdFile file;
  char name[MAX_FILENAME];
  
  Serial.println ();  
  Serial.println (F("HEX files in root directory:"));  
  Serial.println ();  

  // back to start of directory
  sd.vwd()->rewind ();
  // open next file in root.  The volume working directory, vwd, is root
  while (file.openNext(sd.vwd(), O_READ)) {
      
    file.getFilename(name);
    byte len = strlen (name);
      
    if (len > 4 && strcmp (&name [len - 4], ".HEX") == 0)
      {
    Serial.println (name); //WORKS PERFECTLY HERE
        directory[0][fileCounter] = filename; 
        Serial.println(directory[0][fileCounter]); //WORKS PERFECTLY HERE TOO
        fileCounter++;
      }
      file.close();
           
    }  // end of listing files
    
   for(int j=0; j<=fileCounter; j++){
      Serial.print(j);
      Serial.print(directory[0][j]); //HERE I GET ONLY REPEATING FILE NAMES
    }
  }  // end of showDirectory

The only place I can find ‘filename’ is here:

        directory[0][fileCounter] = filename; 
        Serial.println(directory[0][fileCounter]); //WORKS PERFECTLY HERE TOO
        fileCounter++;

Did you mean ‘name’ instead.

If so, you are only copying the pointer of ‘name’ so all elements in ‘directory’ point to the same variable.

When you loop, the array contents of ‘name’ is changed. So when you print using an element in ‘directory’ it is really just accessing ‘name’.

   for(int j=0; j<=fileCounter; j++){
      Serial.print(j);
      Serial.print(directory[0][j]); //HERE I GET ONLY REPEATING FILE NAMES
    }

If you want to keep the text, you’ll need an array of chars to put the data in, instead of an array of pointers.


Here is an overview of how you could handle the problem:

#define MAX_FILES         10
#define MAX_FILE_LENGTH   20

char directory[ MAX_FILES ][ MAX_FILE_LENGTH ] = {};  //{} will null terminate all data.

//...
//In your loop, get the name directly into array:

file.getFilename( directory[fileCounter] );
fileCounter++;

//...
//Loop names

for( int idx = 0 ; idx < fileCounter; ++idx ){
	Serial.println( directory[idx] );
}

That worked perfectly. I'm a bit of a c++ noob, so had no idea that I was storing a pointer and it would behave like that. I'll be sure to read up on it, thanks a lot!