Christmas Eve Code Challenge (getting strcopy() to work)

I have a an array of strings (not an array of chars) and I want top copy the elements to another array, but I can't get strcpy() to work. No compile errors, it just wont run

Anyone lend me a hand?

just using strcpy(New, Old); will not work

const char *Old[10] = {"Red", "Green", "Blue"};
char *New[10];

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

void loop() {

  CopyStringsDarnIt(Old);

  for (int k = 0; k < 10; k++) {
    Serial.println(New[k]);
  }

}

void CopyStringsDarnIt(const char *old[]) {

  Serial.println("ok upto here");

  for (int k = 0; k < 10; k++) {
    Serial.println(k);
    Serial.println(Old[k]);
    strcpy(New[k], Old[k]);
    Serial.println("strcpy fails why....");
  }

}

Because your New array is unallocated. Use strdup() instead. But remember to free the memory if you're done.

Iv'e never heard of strdup() so my knowledge of it's usage is limited so how do you free memory?

Old[] and New[] are arrays of char pointers. strcpy() is used to copy a null-terminated char array, not a char *. To copy the char pointers, just use an assignment operator.

const char *Old[10] = {"Red", "Green", "Blue"};
char *New[10];

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

void loop() {
  CopyStringsDarnIt(Old);
  for (int k = 0; k < 10; k++) {
    Serial.println(New[k]);
  }
}

void CopyStringsDarnIt(const char *old[]) {
  Serial.println("ok upto here");
  for (int k = 0; k < 10; k++) {
    Serial.println(k);
    Serial.println(Old[k]);
    New[k] = Old[k];
    //need to cast Old[k] to (char *)Old[k] otherwise compiler will give a nuisance warning about an invalid conversion
    //strcpy(New[k], Old[k]);
    Serial.println("strcpy fails why....");
  }
}

It seems pointless to copy these. What are you trying to do?

KrisKasprzak:
I have a an array of strings (not an array of chars) and I want top copy the elements to another array, but I can't get strcpy() to work. No compile errors, it just wont run

Anyone lend me a hand?

just using strcpy(New, Old); will not work

This seems to work fine:

#define NUMBER_OF_STRING_ELEMENTS 3
#define MAX_STRING_LENGTH 10

const char Old[NUMBER_OF_STRING_ELEMENTS][MAX_STRING_LENGTH] = {"Red", "Green", "Blue"};
char New[NUMBER_OF_STRING_ELEMENTS][MAX_STRING_LENGTH];

void CopyStringsDarnIt(const char old[][MAX_STRING_LENGTH]) {
  for (int k = 0; k < NUMBER_OF_STRING_ELEMENTS; k++) {
    Serial.print(k);
    Serial.print(" ");
    Serial.println(Old[k]);
    strcpy(New[k], Old[k]);
  }
}

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

void loop() {
  CopyStringsDarnIt(Old);

  for (int k = 0; k < NUMBER_OF_STRING_ELEMENTS; k++) {
    Serial.println(New[k]);
  }
}

sherzaad:
This seems to work fine:

#define NUMBER_OF_STRING_ELEMENTS 3

#define MAX_STRING_LENGTH 10

const char Old[NUMBER_OF_STRING_ELEMENTS][MAX_STRING_LENGTH] = {"Red", "Green", "Blue"};
char New[NUMBER_OF_STRING_ELEMENTS][MAX_STRING_LENGTH];

void CopyStringsDarnIt(const char old[][MAX_STRING_LENGTH]) {
 for (int k = 0; k < NUMBER_OF_STRING_ELEMENTS; k++) {
   Serial.print(k);
   Serial.print(" ");
   Serial.println(Old[k]);
   strcpy(New[k], Old[k]);
 }
}

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

void loop() {
 CopyStringsDarnIt(Old);

for (int k = 0; k < NUMBER_OF_STRING_ELEMENTS; k++) {
   Serial.println(New[k]);
 }
}

That will work if you actually want to copy the text strings themselves, instead of just the pointers to the strings, but can consume a considerable amount of memory, and is quite wasteful of memory if one of the strings is considerable longer than the others.

All of the code examples posted so far are needlessly passing an argument to the CopyStringsDarnIt() function and never using it, using Old[] inside the function instead of old[]

Also be careful in the original code, you declared Old[] as an array of ten char *, but only initialized the first three, which will cause unpredictable results from the print statements.

KrisKasprzak:
I have a an array of strings (not an array of chars)

You actually have an array of pointers to strings.
Two big issues in the code:

  • only 3 of the 10 pointers are valid in Old[] (so the loop going 0 to 9 is attempting to use uninitialized pointers with strcpy() )
  • strcpy() cannot be used given that all the destination address pointers in New[] are zero and there is no space allocated to store them.

The Old[] array is a array of 10 pointers, the first 3 are addresses that point to the strings you provided, the remaining 7 pointers are zero.
The New[] array is array of 10 pointers, all of which are set to zero by the compiler/linker/startup code since the array was not initialized.

As david pointed out, you would not use strcpy() to put the pointer to the string from Old[] into New[]
You would simply copy the pointer from Old[] to New[] using assignment.

If you use strcpy() you trying to copy the string pointed to by the indexed element in Old[] to the indexed element address pointer in New[]
Only the first 3 elements of Old[] actually have valid pointers and none of the elements in New[] are valid since they all point to zero.

I too am curious as to what you are really wanting/trying to do.

--- bill

not sure what strdup() is but if you post why and what data is being sent and what you want to get from it I can help.

when dealing with strings data is generally about splitting and parcing on the recieving end.... hopefully you are sending your data with proper seperator characters.

taterking:
not sure what strdup()

Read the man page.
It could be used to do what the OP said he wanted.

However, I don't understand the need to make a copy of the string when it is possible to simply use a pointer to reference the same original string.

--- bill