Reputation: 95
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 strlen
the 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:
Output as text:
Name received: dog
The sentence entered is 5 characters long
Upvotes: 6
Views: 10588
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:
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
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
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
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