SD card textfile to char* array?

Hello,

I have written this code to read a text file from an SD card, the file contains the definitions for an IR remote, the file is in the format = #, as in the extract below:

C0E8=PWR  # Power
C091=PLY  # Play
C04D=REC  # Record
C061=STP  # Stop
C001=PSE  # Pause
C07D=FFW  # Fast Forward

What want to do is read the IR code into an char* array and my attempt to do this does not work:

#include <SD.h>
File myFile;

char* irCommand[33];

boolean setIRbuttons() {
  char irCmd[5]; 
  int i = 0;
  int ic = 0;
  int ne = 0;

  myFile = SD.open("IR_SONY.TXT");
  if (myFile) {
    while (myFile.available()) {
      int c = myFile.read();
      if (i < 4) {  // read first four bytes of line
        irCmd[ic++] = c;
        irCmd[ic] = '\0';
      }   
      
      i++;
      if (c == '\n' || c== '\r') {
        i = 0;  // end of line reached, reset some line counters
        ic = 0;       
        Serial.print(ne);
        Serial.print(". irCmd: "); 
        Serial.println(irCmd);          // print the char
        irCommand[ne] = irCmd;     // add the line to the array
        Serial.print(ne);
        Serial.print(". irCommand: ");
        Serial.println(irCommand[ne]);  // print the array
        ne++;
      }
    }
    myFile.close();
  } 
  else {
    Serial.println("could not open ");
    return false;
  }
  return true;
}

void setup() {

  Serial.begin(9600);

  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  if (!SD.begin(4)) {
    Serial.println("failed!");
    return;
  }
  Serial.println("done.");
  
  setIRbuttons();

  Serial.println("irCommands in array"); 
  for (int i=0; i < 33; i++) {
    Serial.print(i);
    Serial.print(". ");
    Serial.println(irCommand[i]);
  }

}

void loop()
{
  // nothing happens after setup
}

it is supposed to copy each IR command into irCommand. But I end up with each element or irCommand containing only the last command processed, as in this extract of the output:

Initializing SD card...done.
0. irCmd: C0E8
0. irCommand: C0E8
1. irCmd: C091
1. irCommand: C091
2. irCmd: C04D
2. irCommand: C04D
3. irCmd: C061
3. irCommand: C061
4. irCmd: C001
4. irCommand: C001
5. irCmd: C07D
5. irCommand: C07D
ir commands in array
0. C07D
1. C07D
2. C07D
3. C07D
4. C07D
5. C07D

can anyone explain why irCommand is not being filled in? I wrote a little test programme to try this, which does work:

char* copyCat[6];

boolean satCat() {
  char* catSat[] = {"The", "Cat", "Sat", "on", "the", "Mat"};
  for (int i=0; i < 6; i++) {
    Serial.print(i);
    Serial.print(". ");
    Serial.println(catSat[i]);  
    copyCat[i] = catSat[i];
  }   
  return true;
}

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

  Serial.println("copied cat");  
  for (int i=0; i < 6; i++) {
    Serial.print(i);
    Serial.print(". ");
    Serial.println(copyCat[i]);   
  }
  
}

void loop()
{
  // nothing happens after setup
}

which has left me confused.

can you help?
Thanks
Karl

What want to do is read the IR code into an char* array

Please explain why you want to do this.

char* irCommand[33];

This is an array of 33 pointers that point nowhere. You can not write to the place that these point to until you make them point somewhere.

        irCommand[ne] = irCmd;     // add the line to the array

This does not make a copy of the data. All it does is say that this pointer points to the memory known as irCmd.

Having 33 pointers point there hardly seems useful.

I suspect that a 2D array of chars would be far more suitable for your purpose.

I want to have one array contain the IR code (C0E8) and another array to have the IR command (PWR), so I can lookup the IR code to give an human understandable response.

if irCommand[ne] = irCmd; does not make a copy of the data then how come it works in my catSat example?

I thought I was creating a 2D array?

irCommand[0] = "C0E8";
irCommand[1] = "C091";
etc...

I mostly program in Python and PHP, this stuff is rather different.

Thanks.
Karl

if irCommand[ne] = irCmd; does not make a copy of the data then how come it works in my catSat example?

Is that snippet from your catSat example? If so, the compiler creates space for each literal. The pointer then points to that space. The space for each literal is different, so the pointers all point to different spaces.

I want to have one array contain the IR code (C0E8) and another array to have the IR command (PWR), so I can lookup the IR code to give an human understandable response.

You can do that. An array of pointers is not necessary, though.

Declare an array that can hold 5 characters per value by 33 values:

char IRCodes[5][33];

Make sure that the n characters per value is enough to contain the trailing NULL, too.

Hello,

Sorry, but your reply is not giving me enough information to go on.

After some experimentation, I can't see how to add an IR code to the array: char IRCodes[5][33];

Karl.

I can't see how to add an IR code to the array: char IRCodes[5][33];

You know which row the value is for, right?

Say it's the row in rowNum.

To write a character into the array for that row, use
IRCodes[something][rowNum] = someNewValue.

So, what is something? It's the nth character in the IR code you are reading from the file.

You would have a loop like this:

byte index = 0;
byte rowNum = 0;
while(file.available() > 0)
{
   char someChar = file.read();
   if(comeChar != '\n' && someChar != '\r')
   {
      IRCodes[index][rowNum] = someChar;
      index++;
      IRCodes[index][rowNum] = '\0';
   }
   else
   {
      if(index > 0)
         rowNum++;
      index = 0;
   }
}