clearing a string

I'm just wondering which one is better to clear a char array, why, and pros and cons of each.

memset()

char input[40] = "Text to be deleted";

void setup() {
   memset(input, 0,sizeof(input));
   Serial.print("input: ");
   Serial.println(input);
}

void loop() {
}

vs.

for()

char input[40] = "Text to be deleted";

void setup {
   for(int i = 0; i < sizeof(input) - 1; i++) {
      input[i] = 0;
   }
   Serial.print("input: ");
   Serial.println(input);
}

void loop() {
}

Thanks

Since a string ends at the first NULL character: input[0]= '\0';

johnwasser:
Since a string ends at the first NULL character: input[0]= '\0';

:slight_smile: Correct.

But to answer what the OP asked, rather than what they probably meant, use memset. It will be hand-crafted in assembler. It may even be the case that the compiler "knows" about those utility functions and does some magic assembler that's better than anything you could get by coding in C.

Reply #1 is the most efficient way.

@aarg: Agreed, but the OP said to "clear the array". John's solution truncates the array and assumes it's being used as a string while memset() clears it. Well...at least that's the way I would read it.

This does not clear the last character:

   for(int i = 0; i [color=red]<[/color] sizeof(input) [color=red]- 1[/color]; i++) {
      [nobbc]input[i] = 0;[/nobbc]
   }

econjack:
@anon57585045: Agreed, but the OP said to "clear the array". John's solution truncates the array and assumes it's being used as a string while memset() clears it. Well...at least that's the way I would read it.

That is worth noting. But it definitely worth pointing out that it is usually not necessary with a char string.

oqibidipo:
This does not clear the last character:

   for(int i = 0; i [color=red]<[/color] sizeof(input) [color=red]- 1[/color]; i++) {

[nobbc]input[i] = 0;[/nobbc]
  }

but the last character in the string is already a NULL character, right?

AbnerDoubledeal:
but the last character in the string is already a NULL character, right?

So are all the characters after the last 'd' in "deleted" - what's your point?

At the risk of embarrassing myself, why not just reinitialize the array?

char myArray[] = "Hello World";

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

    Serial.print("myArray : ");
    Serial.println(myArray);

    strcpy(myArray, "");

    Serial.print("myArray : ");
    Serial.println(myArray);

}

void loop() {
}

Output:

myArray : Hello World
myArray :

Edit : FWIW if u wanted to assign a new value to the array, u don't really need to clear it, just use strcpy() to assign the new value.

At the risk of embarrassing myself, why not just reinitialize the array?

Because what you suggest doesn't reinitialise the array, it just writes a zero to the first element.

AWOL:
Because what you suggest doesn't reinitialise the array, it just writes a zero to the first element.

If that were the case, I would expect the array to print as " ello World" - or am I mistaken?

or am I mistaken?

Yup.

char myArray[] = "Hello World";

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

    Serial.print("myArray : ");
    Serial.println(myArray);

    strcpy(myArray, "");

    Serial.print("myArray : ");
    Serial.println(&myArray[1]);

}

void loop() {
}

I'm just wondering which one is better to clear a char array, why, and pros and cons of each.

Do you want to fill the array with zeroes or do you want to set the first level to zero in preparation for adding characters one by one later ? If the latter, then you would normally add the terminating zero after each character added.

Of course, using an array of chars does not actually mean that it is being used as a string anyway so the terminating zero may not be needed in the first place.

but the last character in the string is already a NULL character, right?

Probably yes if it is a "c-string" stored in a memory location. A string of bytes is just an ordered set of bytes. How the bytes are stored in memory and indexed/referenced probably can vary depending on the programming you are using.

AWOL:
Yup.

char myArray[] = "Hello World";

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

Serial.print("myArray : ");
    Serial.println(myArray);

strcpy(myArray, "");

Serial.print("myArray : ");
    Serial.println(&myArray[1]);

}

void loop() {
}

Noted and thanks for the explanation.

As it turns out, I needed to do something similar within a function a few days ago, where I was using a buffer.

My solution was to do this :

  char buffer[75];
  int bufSize = sizeof(buffer);
  Serial.print("Buffer Size : ");
  Serial.println(bufSize);

  //Flush Buffer
  for (int i = 0; i <= bufSize; i++) {
  buffer[i] = '\0';
  }

Sketch uses 14,480 bytes (5%) of program storage space. Maximum is 253,952 bytes.
Global variables use 1,297 bytes (15%) of dynamic memory, leaving 6,895 bytes for local variables. Maximum is 8,192 bytes.

Today I remembered this thread and thought I would check/test the solutions offered here.

The answer in reply#1 does not work for my sketch - It sends the function into a continuous loop.

  char buffer[75];
  int bufSize = sizeof(buffer);
  Serial.print("Buffer Size : ");
  Serial.println(bufSize);

  //Flush Buffer
  buffer[0] = '\0';

The answer in reply #4 worked.
I used it like this :

  char buffer[75];
  int bufSize = sizeof(buffer);
  Serial.print("Buffer Size : ");
  Serial.println(bufSize);

  //Flush Buffer
  memset(buffer, '\0', bufSize);

Sketch uses 14,474 bytes (5%) of program storage space. Maximum is 253,952 bytes.
Global variables use 1,297 bytes (15%) of dynamic memory, leaving 6,895 bytes for local variables. Maximum is 8,192 bytes.

The memset() version compiles slightly smaller than my version, but which is more efficient?

The answer in reply#1 does not work - It sends the function into a continuous loop.

Can you please post an example of this not working. Putting a '\0' in position 0 of the char array is not enough if your program does not populate the array properly later with a replacement string terminated by a '\0'

Bear in mind my post relates to my specific sketch - it may well work in other sketches.

The buffer is populated with the contents of a file read from an SD card :

datFile.readBytes(buffer, bufSize);

I do not explicitly null terminate after reading the contents.

Because the sketch reads files of different lengths, I need to clear the buffer.

Unless of course one could arrange to read the files from smallest to largest, then clearing won't be required.

Bear in mind my post relates to my specific sketch - it may well work in other sketches.

The buffer is populated with the contents of a file read from an SD card :

I would have borne it in mind had I known it. As a matter of interest which SD library are you using ?

UKHeliBob:
I would have borne it in mind had I known it. As a matter of interest which SD library are you using ?

I thought my post clearly stated the posted code related a sketch of mine when I wrote :

As it turns out, I needed to do something similar within a function a few days ago, where I was using a buffer.

I am using the SdFat library.