Xirb
Xirb

Reputation: 95

What is the best way of clearing a char array in C/C++?

I've been searching for ways of emptying a char array in C/C++. I have come up with this code:

char testName[20];   

for(int i = 0; i < sizeof(testName); ++i)
{
  testName[i] = (char)0;
}  

It has been working for a while now but when I try to strlenthe result is always two more than the typed in word. For instance I input the word dog the output would be five. Why is that so? Is my char array not cleared?

Here is my code:

char testName[20];
void loop()
{
  if(Serial.available())
  {
    Serial.println("Waiting for name...");
    index = 0;
    for(int i = 0; i < sizeof(testName); ++i)
    {
        testName[i] = (char)0;
    }
    while(Serial.available())
    {
      char character = Serial.read();
      testName[index] = character;
      index++;
    }
    Serial.print("Name received: ");
    Serial.println(testName);
    Serial.print("The sentence entered is ");
    Serial.print(strlen(testName));
    Serial.println(" long");
    delay(1000);
  } 
  delay(1000);
}

Screenshot of the output:

Screenshot of the output

Output as text:

Name received: dog

The sentence entered is 5 characters long

Upvotes: 6

Views: 10588

Answers (4)

Bisquick19
Bisquick19

Reputation: 1

For posterity. The OP example is an Arduino sketch. Assuming here that the input is taken through the built-in Serial Monitor of the Arduino IDE. At the bottom of the Serial Monitor window is a pop-up menu where the line ending can be selected as:

  • No line ending
  • newline
  • Carriage return
  • Both NL & CR

Whatever option is selected in this menu is appended to whatever is entered in the box at the top of the Serial Monitor when the Send button is clicked or the return key is hit. So the extra two characters are most certainly the result of having the "Both NL & CR" menu option selected.

Picking the "No line ending" option will solve the problem.

FWIW, in this application, the array does not need to be "cleared". Just append a '\0' char to the last char received to make it a C-string and all will be good.

Upvotes: 0

p-a-o-l-o
p-a-o-l-o

Reputation: 10079

Yet another quick way of filling an array with zeroes, in initialization only:

char testName[20] = {};

same as

char testName[20] = {0};

Since it is a C99 feature, compiler could complain with the following

warning: ISO C forbids empty initializer braces

More here.

Anyway, looking at the OP code, there's no need at all of initializing/filling the array, it could be better like this:

#define MAX_LENGTH 20
char testName[MAX_LENGTH];
void loop()
{
  if(Serial.available())
  {
    Serial.println("Waiting for name...");
    index = 0;
    while(Serial.available())
    {
      if(index < MAX_LENGTH) 
          testName[index++] = Serial.read();
    }
    if(index < MAX_LENGTH)
    {
      testName[index] = 0;
      Serial.print("Name received: ");
      Serial.println(testName);
      Serial.print("The sentence entered is ");
      Serial.print(strlen(testName));
      Serial.println(" long");
    }
    else
      Serial.print("Name too long ...");

    delay(1000);
  } 
  delay(1000);
} 

Upvotes: 2

Mateusz Grzejek
Mateusz Grzejek

Reputation: 12108

If your definition of "emptying char array" is set all elements of an array to zero, you can use std::memset.

This will allow you to write this instead of your clear loop:

const size_t arraySize = 20;  // Avoid magic numbers!
char testName[arraySize];
memset(&(testName[0]), 0, arraySize);

As for "strange" results of strlen():

strlen(str) returns "(...) the number of characters in a character array whose first element is pointed to by str up to and not including the first null character". That means, it will count characters until it finds zero.

Check content of strings you pass to strlen() - you may have white characters there (like \r or \n, for example), that were read from the input stream.

Also, an advice - consider using std::string instead of plain char arrays.


Small note: memset() is often optimized for high performance. If this in not your requirement, you can also use std::fill which is a more C++ - like way to fill array of anything:

char testName[arraySize];
std::fill(std::begin(testName), std::end(testName), '\0');

std::begin() (and std::end) works well with arrays of compile-time size.


Also, to answer @SergeyA's comment, I suggest to read this SO post and this answer.

Upvotes: 10

doron
doron

Reputation: 28932

Don't use C style arrays in modern C++. When you require a fixed size array, use std::array instead. From a memory storage point of view, they are identical.

You can then clear the array with: myarray.fill('\0')

Upvotes: 15

Related Questions