Writing char* Array problem

Hi!

I’m still having a hard time understanding this problem hope you can help me, so I’m writting stuff in the Serial monitor window and I’m able to put that into a array but after, I want to take that result and put it into a char* array, for a reason I don’t understand on the first pass it looks like that assuming that I wrote Red in the terminal and my array already had some stuff into it:

Result:
Red
Green
Yellow

But on the second an others subsequent pass if I write other stuff it looks like that:
Result:
Car
Car
Yellow

It takes the latest stuff that I wrote and instead of putting it at the second position it write it on the first and second, on the third pass on the first,second and third position and so on…

The code looks like that, I’ve put only the section where it writes to the array taking account that the int n was set to 0 in the header.

void showNewData() {
 if (newData == true) {
 Serial.print("This just in ... ");
 Serial.println(receivedChars); //The result after /n and adding /0 from the terminal window
 Serial.println(n);// printing just for troubleshooting the position in the array
 allChars[n]=receivedChars; //allChars is the char* array that I'm trying to write to.
 n++; //increment for the next time to write in the next position of the array
 int i;
 for (i=0; i<4; i++){
  Serial.println(allChars[i]); // printing for troubleshooting the whole array allChars
 }
  newData = false;
 }
}
 allChars[n]=receivedChars; //allChars is the char* array that I'm trying to write to.

At the end, all the pointers point to the same array, so it is no surprise that when you print what the pointers point to, everything is the same.

strdup() will copy the pointed to data, and return a pointer to the copy, that you can store in the array (and free when you are done with it).

That’s the second time I have that answer and I don’t understand…

If I declare n=0 at the begining and then at the end of the loop I wrote n++ n is incrementing right???

I’m printing it in the serial monitor and it increment!!! What am I missing???

The same array receivedChars is the result of the serial terminal and allChars is the array where I put this result, it’s not the same array right?

Mega confuse… been working on that for 4 days and can’t get it right.

So in your first example receivedChars contains "red" and you make allChars[0] point to receivedChars and when you print allChars[0] it prints "red". But allChars doesn't contain "red" it just points to receivedChars.

Next you put "car" in receivedChars. And allChars[0] still points to receivedChars which no longer contains "red" it now contains "car" so when you print allChars[0] you get "car".

Ho Man!!!! Now I get it.... I'm so dumb!!!!!

Ok now I understand what I want to do is:
allChars[0]=receivedChars //Red
allChars[1]=receivedChars //Green...and so on

How can I do that?

audioguru67:
Ho Man!!!! Now I get it.... I'm so dumb!!!!!

Ok now I understand what I want to do is:
allChars[0]=receivedChars //Red
allChars[1]=receivedChars //Green...and so on

How can I do that?

I don't think you get it. Look at what you wrote. If allChars[0] and allChars[1] are BOTH equal to receivedChars then they can't possibly be one printing red and one printing green. receivedChars can't be both things at once.

I think what you want to do is not to make allChars[0] point to received chars but to a copy of what receivedChars had in it at that point in time. In that case you can use strdup to make a new thing that is a copy of what was in receivedChars and make allChars[0] point to that. But you have to be sure to remember to free that memory when you're done or you're going to crash your arduino. Then receivedChars could get a new value and allChars[0] points to a copy of what receivedChars used to have so printing allChars[0] would print whaqt receivedChars used to contain.

Yes you are right, I don't want to point I want to copy what is in receivedChars and write it in the allChars array.

Where can I find a good tutorial on strdup it seems that it's not a usual function with Arduino and more a C++

audioguru67:
Yes you are right, I don't want to point I want to copy what is in receivedChars and write it in the allChars array.

Where can I find a good tutorial on strdup it seems that it's not a usual function with Arduino and more a C++

Have you tried googling it?

Yes and there is not a lot of result...

I found that...
http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html

That's about it...

Finally got some result going on with strncpy I was able to copy one array to the other but sometimes I have weird result… I need to find why.

Here is my code for the copy section

void showNewData() {
 if (newData == true) {
 Serial.print("This just in ... ");
 Serial.println(receivedChars);
 Serial.println(n);
 strncpy(allChars[n], receivedChars, 8);// Copy the content of receivedChars to allChars
 n++; 
 int i;
 for (i=0; i<4; i++){
  Serial.println(allChars[i]);
 }
  newData = false;
 }
}

Show the whole thing. How is allChars defined? If it is just an array of pointers with no storage allocated then you are stomping on memory you don't own and that can cause all kinds of crazy stuff to happen.

Here is the entire code, to make it work properly I had to pre-format allChars at the begining.

const byte numChars = 32; //Maximum byte
char receivedChars[numChars]; // an array to store the received data

char* allChars[]={"aaaaaa","bbbbbb","cccccc","dddddd","eeeeee","ffffff"};
int n=0; //Position of the allChars Array

boolean newData = false;


void setup() {
 Serial.begin(9600);
 Serial.println("<Arduino is ready>");
}

void loop() {
 recvWithEndMarker();
 showNewData();
}

void recvWithEndMarker() {
 static byte ndx = 0;
 char endMarker = '\n';
 char rc;
 
 // if (Serial.available() > 0) {
           while (Serial.available() > 0 && newData == false) {
 rc = Serial.read();

 if (rc != endMarker) {
 receivedChars[ndx] = rc;
 ndx++;
 if (ndx >= numChars) {
 ndx = numChars - 1;
 }
 }
 else {
 receivedChars[ndx] = '\0'; // terminate the string
 ndx = 0;
 newData = true;
 
 }
 }
}

void showNewData() {
 if (newData == true) {
 Serial.print("This just in ... ");
 Serial.println(receivedChars);
 Serial.println(n);
 memcpy(allChars[n], receivedChars, 6);
 n++; 
 int i;
 for (i=0; i<6; i++){
  Serial.println(allChars[i]);
 }
  newData = false;
 }
}

Next step is to replace the Serial terminal for a SD card but that step used to work… so I hope it won’t be such a pain :slight_smile:

Try running this program:

#define MAXLENGTH 33

char allChars[10][MAXLENGTH];  // Room for 10 entries of 32 or few characters, one for NULL
int index;

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

void loop() {
  char temp[MAXLENGTH];
  int charsRead;
  int entries = 0;
  

  Serial.println("Enter up to 32 characters and press Enter. Enter # to end.");

  while (true) {
    if (Serial.available() > 0) {
      charsRead = Serial.readBytesUntil('\n', temp, sizeof(temp) - 1);
      temp[charsRead] = NULL;
      if (temp[0] == '#' || entries > 9) {         // Done entering stuff
        break;                
      } else {
        strcpy(allChars[entries], temp);
        entries++;                                 // Move to next one...
      }
    }
  }
  for (int i = 0; i < entries; i++) {
    Serial.println(allChars[i]);
  }
}

Enter test data on the Serial monitor’s Send textbox, pressing Enter after each entry. Enter ‘#’ and Enter to end the test data stream. See if you can work your way through the code to understand what the other posters are saying.

Awesome! I'll give it a try!

The strdup() function is dirt simple to use.

   char *ptr = strdup(receivedChars); // Make a copy of that is in receivedChars

Ok I'll try it as well Paul, Thanks :slight_smile:

Woaw Paul S, your line of code works perfectly!!!!

   char *ptr = strdup(receivedChars); // Make a copy of that is in receivedChars

I'll use that instead of what I had before, it's more concise!

Thanks a lot.

Just keep in mind that it is using dynamic memory allocation, and that you need to free() the memory when you are done with it.

OK...I'll Google it because I've never done that before... :o