Problem with a char* Array & SDFat's "getName" function

Hello,

I’m trying to list all files from my SD Card into an array then printing out that array of files into my serial monitor with the following format:

(The ID is not the actual Index of the file on the SD Card)

It should look like this:

Files:
0 FILE_001
1 FILE_002
2 FILE_003
3 FILE_004
4 FILE_005

Without the extension which is .txt.

I attempted this with the following sketch:

#include <SPI.h>
#include "SdFat.h"

SdFat SD;
SdFile File;
SdFile DirFile;

const uint8_t SD_CS_Pin = SS;
const uint16_t MaxNumberOfFiles = 5;

uint16_t NumberOfFiles = 0;

char* FileName[MaxNumberOfFiles];

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

    while(!Serial){}

    delay(10);

    Serial.println("Checking for SD Card availability...");

    delay(1000);

    if(!SD.begin(SD_CS_Pin))
    {
        Serial.print("No SD Card was found.");

        return;
    }

    Serial.println("SD Card was found, checking for SD Card stability...");

    delay(1000);

    if(!DirFile.open("/", O_READ))
    {
        Serial.print("There was an Error with the SD Card.");

        return;
    }

    ListFilesFromCard();
}

void loop(){}

void ListFilesFromCard()
{
    Serial.println("Everything went well...");
    Serial.println("Files:");
        
    while(NumberOfFiles < MaxNumberOfFiles && File.openNext(&DirFile, O_READ))
    {
        if(!File.isSubDir() && !File.isHidden())
        {
            File.getName(FileName[NumberOfFiles], 8); // Max length should be 8 right? Because "FILE_00X" without extension has 8 characters

            Serial.print(NumberOfFiles);
            Serial.write(' ');
            Serial.println(FileName[NumberOfFiles]);

            NumberOfFiles++;
        }
        
        File.close();
    }
}

The problem is that it does not print out the names of the files. It doesn’t print anything at all. Like this:

Files:
0
1
2
3
4

Thanks in advance.

char* FileName[MaxNumberOfFiles];

This is an array of pointers. Where do they point? Nowhere.

            File.getName(FileName[NumberOfFiles], 8); // Max length should be 8 right? Because "FILE_00X" without extension has 8 characters

This function expects an array that it can write to, or a pointer to some memory that it can write to. That is NOT what you are supplying.

Hello,

Could you show an example or links/keywords to sites that might help me out with the operations?

Thanks.

0z_R3n:
Hello,

Could you show an example or links/keywords to sites that might help me out with the operations?

Thanks.

I'm not sure what you are asking for. You know how many characters in the file names, so just use a 2D array:

const uint8_t MaxNumberOfFiles = 5;
const uint8_t MaxNumberOfChars = 8;

char FileNames[MaxNumberOfChars][MaxNumberOfFiles];

Notice that I changed the type of the variables. There is no reason to allow 65000+ names. You don't have near that much memory. Note, too, that I made the array name plural, because it holds more than one name.

Reserve enough space in a character array for the longest possible file name, plus 1 for the zero terminator, e.g.

char filename[10];

Use that in the call to Flle.getName instead. Do some reading about C-strings (character arrays).

Hello,

Thanks for improving some silly mistakes I made. But I'm confused with the dimensions. I have modified the vars.

char* FileNames[MaxNumberOfChars + 1][MaxNumberOfFiles + 1]; // I forgot about the zero terminator

Now, what should I do here?

File.getName(FileNames[NumberOfFiles], 8);

Each dimension of the array should have an obvious starting point there, right?
So I did this.

File.getName(FileNames[0][NumberOfFiles], 8);

And It works the same. It does not print out the names.

I'm sorry, I'm not an expert in programming.

Also, why did you put char instead of char*? The getName throws an error when I use char because it accepts char*.

The char* is a pointer. It's like an address. The char array is like the house at that address. You want all the characters in the file name to move into the house. So you need a pointer that points to an actual array, you need the address of an actual house. Right now you are creating pointers but they don't point to any actual space in memory. So it's like you are sending your friends to stay at an address where there is no house.

You need to create arrays of char and then pass that function a pointer that points to one of them.

I'm sorry, I'm not an expert in programming

We can tell, and also that you are not following advice to read up on character arrays and C-strings, or the difference between variables and pointers.

jremington:
We can tell, and also that you are not following advice to read up on character arrays and C-strings, or the difference between variables and pointers.

Nvm. Got it fixed.

Please explain what is confusing you, and what happened when you tried our suggestions.

Be sure to post the relevant code using code tags.

char FileNames[MaxNumberOfFiles + 1][MaxNumberOfChars + 1];

File.getName(FileNames[NumberOfFiles], (MaxNumberOfChars - 1));

Serial.println(FileNames[NumberOfFiles]);

Prints out empty.

Can you make it work using a 1D array for ONE name? If so, you can always copy that name to the 2D array.

Try

char FileNames[MaxNumberOfChars + 1];
File.getName(FileNames, MaxNumberOfChars);
FileNames[MaxNumberOfChars]=0; //ensure  termination
Serial.println(FileNames);

Hello,

I tried getting only one name into a 1dimensional array using that piece of code in mine instead, but without luck, the results are the same.

Here is a novel idea: try out the list files example that comes with the library!

jremington:
Here is a novel idea: try out the list files example that comes with the library!
https://www.arduino.cc/en/Tutorial/listfiles

Well. Thank you, but I'm using the SDFat Library and I'm aiming for saving the files' names into arrays.

There is a similar example for the SDfat lib.

Good luck with your project!

jremington:
There is a similar example for the SDfat lib.

Good luck with your project!

Hello,

I made the current code thanks to that SDFat library example. But it acts the same as the one you recommended with the SD. Please read my post again. I want to store the names of the files into an array.
You asked me to try and only store one name into an 1D array and I did so and gave the results. What happened to that sub-topic of this thread?

Hello,

I managed to find another way of using the files' names multiple times.

Thanks all for your kind help and patience.

You asked me to try and only store one name into an 1D array and I did so and gave the results. What happened to that sub-topic of this thread?

What happened was that you did not post the code that you used to try this, or the results.

Why should anyone continue trying to help you when you appear to ignore suggestions?