What is wrong with this... StrTitlea[0] = subString(str, 1, 3). It has to be something with char*=char*. Maybe I have to resize it, but I doubt it because it's with a pointer. Can someone help me out with this?
Here is my code
char* str;
char line[60];
char** StrTitlea;
int cnt = 0;
while (DbFile.available()) {
int n = DbFile.fgets(line, sizeof(line));
str = line;
StrTitlea[0] = subString(str, 1, 3);
cnt++
}
char* subString(char* s, int index, int n) {
char* res = new char[n + 1];
sprintf(res, "%.*s", n, s + index);
Serial.println(res);
return res;
}
This is the stack I get.
Exception:Error:
e:\documents\visual studio 2019\projects\arduino\sd_card_read_sort_list_sdfat\libraries\sdfat-master\2.1.0\sdfat-master\src\common/arduinofiles.h(63): error 0x400d1480:SortPlaylist(char*, char*)
0x400014fd: ?? ??:0
0x4000150d: ?? ??:0
e:\documents\vs\projects\arduino\sd_card_read_sort_list_sdfat\libraries\sdfat-master\2.1.0\sdfat-master\src\common/arduinofiles.h(63): error 0x400d167c:setup()
C:\Users\user\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32/main.cpp(18): error 0x400d4636:loopTask(void*)
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1):::0x40086161:vPortTaskWrapper
0x40078000: ?? ??:0
0x40080400: ?? ??:0
0x400806a8: ?? ??:0
If I leave this StrTitlea[0] = subString(str, 1, 3) out it doesn't get stuck anymore
char StrTitlea[20][10]; // room for 20 titles of max 9 chars and trailing null
then to copy the substring into the array, you would use strncpy() for example
try something like this:
const byte maxCnt = 20;
const byte maxTitleLength = 9;
char titles[maxCnt][maxTitleLength + 1]; // +1 for the trailing null char
byte cnt = 0;
while (DbFile.available()) {
int n = DbFile.fgets(line, sizeof(line));
if (cnt < maxCnt) {
strncpy(titles[cnt], line + 1, 3); // copy 3 characters starting from second char in line into titles[cnt]
titles[cnt][3] = '\0'; // terminate the cString
// strncat(titles[cnt], maxTitleLength, ".mp3"); // if you want to add ".mp3"
// titles[cnt][maxTitleLength] = '\0'; // just in case terminate the cString
cnt++;
} else {
// handle overflow, too many titles
}
}
Instead of reading the whole entry just to pick the first 3 chars, try reading when serial.available() > 0 one char at a time and save the first 3 in a pre-defined array, dynamic allocation is not a good idea in a small memory environment.
Consider storing the file names and titles in EEPROM that saves through power cycles.
Ok I'm getting the point now Can't set a dynamic in to two dynamic array. Because the memory doesn"t know how much memory it has to located. I was thinking now is evryting constant but it's wasen't for the array's.
this could work indeed.
you have dynamic allocation for the content and so you need to worry about freeing up those bytes at some point possibly
I understand you don't know how many you'll have but at some point (if you have too many) your Arduino will be short in SRAM and because you don't test the allocation (hard on an AVR) you will experience possibly some random crashes.
If you think you won't have more than 20 or 100, just allocate statically the memory for the max usage expected, this way you'll be sure that the rest of the code is not impacted when you'll reach the limit.
post full code. the declaration just creates space for 2 pointers. what they point at depends of the rest of the code
Are you reading filenames off an SD card or some other type of storage?
I would probably go through the directory listing twice, the first time to count how many files there are, then the 2nd time to get the filenames you want. Knowing how many files there are allows you to declare an array within the function with sufficient space to hold all the filenames, and lets you test for some maximum limit on the number of files if you want to limit the memory used.
char line[60]; this allocates 60 bytes of memory, first byte is pointed at by the name of the array
char* str; this allocates (on AVR) 2 bytes for a pointer. it's pointing nowhere at this stage. There is NO memory whatsoever allocated for the text. (you can't copy anything into the space pointed at)
char* StrTitleArray[2]; this allocates (on AVR) 4 bytes of memory as a pointer is 2 bytes and you want space for 2 of those. The pointers are not initialized (unless it's a global variable) and there is NO memory whatsoever allocated for the text. (you can't copy anything into the space pointed at)
you could do str = line;
and now the pointer str would point at the first byte of the memory location the line array is stored
similarly you can do StrTitleArray[0] = line
that would initialise the first pointer in the array to point at the first byte of the memory location the line array is stored
but unless you have memory set aside or dynamically allocated, you can't copy anything in those pointers (str or StrTitleArray[0] or StrTitleArray[1]) as there is no byte reserved for content.