waszee
waszee

Reputation: 11

How to connect a pointer to a const char * [] to data in a String array

I am trying to retrieve a list of radio URL links that are stored on an ESP32 SD Card as character strings that are inside of quotes and separated by commas and a new line. That is one url per line. I am able to open my URL_LIST.TXT file and place the urls into a String array,

String url[100];

by using the SD.H file open, read, and string parsing commands. However the ESP32 Audio kit that I am using wants the urls connected via a const char pointer,

const char *urls[] = {http://urlstation1","http://urlstation2",...,http://lastStation"}

where the urls are defined inside the code and not read from the SD card.

I have tried to create a character array, char u[100][255] to allow up to 100 urls addresses. Each could be up to 255 characters long. The code below is failing even though Serial.Println of the values looks okay.
...

  int readurls(String url[],char u[100][255]){
  File url_list = SD.open("/URLs/URL_LIST.txt");
  String str;
  String a_url;
  int count = 0;
  while (url_list.available() && count < MAX_LINES) {
    str= url_list.readStringUntil('\n');
    //Serial.println(str);
    int delim = str.indexOf(',');
    //a_url=str.substring(0,delim);
    //needed to eliminate the quotes from the strings
    a_url=str.substring(3,delim-1);
    url[count] = a_url;
    // works to this point - that is String Array looks correct 
    a_url+="\0"; // tried to add a null pointer several ways
    //Serial.println(url[count].c_str());
    char ubuf[a_url.length()+1]="";
    a_url.toCharArray(ubuf,a_url.length()+1);
    strncpy(u[count],ubuf,sizeof(u[count]));
    //u[count]=url[count].c_str();
    urls[count]=u[count];
    count++;
  }
  close(url_list);
  return(count);
  }

Hope you experts can tell me what I am doing wrong. When the urls are defined inside of the code using the initialized values the drivers that use the urls pointer plays the music stream.

When the urls are defined in the text file and the url pointer is pointed to get values from the character array the urls are not playing music. Printing the urls[index] of a single station in both cases shows what looks like identical values so something hidden is missing or not done correctly.

Upvotes: 0

Views: 75

Answers (2)

waszee
waszee

Reputation: 11

I found that my problem was with the strings having some extra hidden information that needed to be removed before trying to convert the string to a char * array. After reading the str I added a str.trim() function that cleaned up the string. I was then able to use str.c_str() and get a url address. Without using str.trim() the string printed okay but did not work as a url address.

'''

virtual int size(){
      //read and count the number of stations and store values in String array
        File url_list = SD.open(listurls);
        String str;
        int count = 0;
        while (url_list.available() && count < MAX_LINES) {
          str= url_list.readStringUntil('\n');
          str.trim();
          url_addr[count]=str;
          count++;
        }
        max=count;
        url_list.close();
        return max;

    ...

    char * a_url = url_addr[count].c_str;

'''

Upvotes: 0

CryptoAlgorithm
CryptoAlgorithm

Reputation: 1044

Your code doesn't work because you are trying to assign an instance of String to a char array:

url[count] = a_url;

This does not work - a char array is simply a contiguous section of bytes and not a class instance like String is.

Instead what you should do is first convert the String to a char array with the .c_str() method, which returns a null-terminated char array (basically an array of ascii values), then copy that to your target array with strcpy.

The following is your code modified with the aforementioned suggestions (disclaimer: I did not test this as I do not conveniently have access to the appropriate hardware)

int readurls(String url[],char u[100][255]){
  File url_list = SD.open("/URLs/URL_LIST.txt");
  String str;
  String a_url;
  int count = 0;
  while (url_list.available() && count < MAX_LINES) {
    str = url_list.readStringUntil('\n');
    //Serial.println(str);
    int delim = str.indexOf(',');
    //a_url=str.substring(0,delim);
    //needed to eliminate the quotes from the strings
    a_url = str.substring(3,delim-1);
   
    // Note: must copy the characters, cannot assign because array is not a class but a raw array
    strcpy(url[count], a_url.c_str());
    count++;
  }
  close(url_list);
  return(count);
}

Upvotes: 0

Related Questions