Reputation: 175
I know, the \0
on the end of the character array is a must if you use the character array with functions who expect \0
, like cout, otherwise unexpected random characters appear.
My question is, if i use the character array only in my functions, reading it char by char, do i need to store the \0
at the end?
Also, is it a good idea to fill only characters and leave holes on the array?
Consider the following:
char chars[5];
chars[1] = 15;
chars[2] = 17;
chars[3] = 'c';
//code using the chars[1] and chars[3], but never using the chars
int y = chars[1]+chars[3];
cout << chars[3] << " is " << y;
Does the code above risk unexpected errors?
EDIT: edited the example.
Upvotes: 4
Views: 6425
Reputation: 24269
The convention of storing a trailing char(0) at the end of an array of chars has a name, it's called a 'C string'. It has nothing to do, specifically, with char - if you are using wide character, a wide C string would be terminated with a wchar_t(0).
So it's absolutely fine to use char arrays without trailing zeroes if what you are using is just an array of chars and not a C string.
char dirs[4] = { 'n', 's', 'e', 'w' };
for (size_t i = 0; i < 4; ++i) {
fprintf(stderr, "dir %d = %c\n", i, dirs[i]);
std::cout << "dir " << i << " = " << dirs[i] << '\n';
}
Note that '\0' is char(0), that is it has a numeric, integer value of 0.
char x[] = { 'a', 'b', 'c', '\0' };
produces the same array as
char x[] = { 'a', 'b', 'c', 0 };
Your second question is unclear, though
//code using the chars[1] and chars[3], but never using the chars
int y = chars[1]+chars[3];
cout << chars[3] << " is " << y;
Leaving gaps is fine, as long as you're sure your code is aware that they are uninitialized. If it is not, then consider the following:
char chars[4]; // I don't initialize this.
chars[1] = '1';
chars[3] = '5';
int y = chars[1] + chars[3];
std::cout << "y = " << y << '\n';
// prints 100, because y is an int and '1' is 49 and '5' is 51
// later
for (size_t i = 0; i < sizeof(chars); ++i) {
std::cout << "chars[" << i << "] = " << chars[i] << '\n';
}
Remember:
char one = 1;
char asciiCharOne = '1';
are not the same. one
has an integer value of 1, while asciiCharOne
has an integer value of 49.
Lastly: If you are really looking to store integer numeric values rather than their character representations, you may want to look at the C++11 fixed-width integer types in . For an 8-bit, unsigned value uint8_t, for an 8-bit signed value, int8_t
Upvotes: 3
Reputation: 75795
To me it looks like you use the array not for strings, but as an array of numbers, so yes it is ok not to use '\0'
in the array.
Since you are using it to store numbers, consider using uint8_t
or int8_t
types from stdint.h
, which are typedefs for unsigned char
and signed char
, but is more clear this way that the array is used as an array of numbers, and not as a string.
cout << chars[3] << " is " << y;
is not undefined behaviour because you access the element at position 3 from the array, that element is inside the array and is a char, so everything is fine.
EDIT:
Also, I know is not in your question, but since we are here, using char
instead of int
for numbers, can be deceiving. On most architectures, it does not increase performance, but actually slows it down. This is mainly because of the way the memory is addressable and because the processor works with 4 bytes / 8 bytes operands anyways. The only gain would be the storage size, but use this for storing on the disk, and unless you are working with really huge arrays, or with limited ram, use int for ram as well.
Upvotes: 2
Reputation: 76417
Running off the end of a character array because it has no terminating \0
means accessing memory that does not belong to the array. That produces undefined behavior. Often that looks like random characters, but that's a rather benign symptom; some are worse.
As for not including it because you don't need it, sure. There's nothing magic that says that an array of char has to have a terminating \0
.
Upvotes: 2