开发者

initializing char arrays in a way similar to initializing string literals

开发者 https://www.devze.com 2023-01-07 02:24 出处:网络
Suppose I\'ve following initialization of a char array: char charArray[]={\'h\',\'e\',\'l\',\'l\',\'o\',\' \',\'w\',\'o\',\'r\',\'l\',\'d\'};

Suppose I've following initialization of a char array:

char charArray[]={'h','e','l','l','o',' ','w','o','r','l','d'};

and I also have following initialization of a string literal:

char stringLiteral[]="hello world";

The only difference between contents of first array and second string is that second string's got a null character at its end.

When it's the matter of initializing a char array, is there a macro or something that allows us to put our initializing text between two double quotation marks but where the array doesn't get an extra null terminating character?

It just doesn't make sense to me that when a terminating null charac开发者_StackOverflow中文版ter is not needed, we should use syntax of first mentioned initialization and write two single quotation marks for each character in the initializer text, as well as virgule marks to separate characters.

I should add that when I want to have a char array, it should also be obvious that I don't want to use it with functions that rely on string literals along with the fact that none of features in which using string literals results, is into my consideration.

I'm thankful for your answers.


It's allowed in C to declare the array as follows, which will initialize it without copying the terminating '\0'

char c[3] = "foo";

But it's illegal in C++. I'm not aware of a trick that would allow it for C++. The C++ Standard further says

Rationale: When these non-terminated arrays are manipulated by standard string routines, there is potential for major catastrophe.
Effect on original feature: Deletion of semantically well-defined feature.
Difficulty of converting: Semantic transformation. The arrays must be declared one element bigger to contain the string terminating ’\0’.
How widely used: Seldom. This style of array initialization is seen as poor coding style.


There is no way of doing what you want. The first way of initializing the array specifies separate initializers for each character, which allows to explicitly leave off the '\0'. The second is initializing a character array from a character string, which in C/C++ is always terminated by a null character.

EDIT: corrected: 'character pointer' --> 'character array'


litb has the technically correct answer.

As for an opinion - I say just live with the 'waste' of the extra '\0'. So many bugs are the result of code expecting a terminating null where one isn't (this advice may seem to go directly against some other advice I gave just a day or two ago about not bothering to zero an entire buffer. I claim there's no contradiction - I still advocated null terminating the string in the buffer).

If you really can't live with the '\0' terminator because of some semantics in the data structure you're dealing with, such as it might be part of some larger packed structure, you can always init the array yourself (which I think should be no less efficient than what the compiler might have done for you):

#define MY_STRING_LITERAL "hello world"

char stringLiteral[sizeof(MY_STRING_LITERAL) - 1];

memcpy( stringLiteral, MY_STRING_LITERAL, sizeof(stringLiteral));


The basic answer is that the vast majority of char arrays are strings - in C, strings are null terminated. C++ inherited that convention. Even when that null isn't needed, most of the time it isn't a problem just to leave it there anyway.

Macros aren't powerful enough to do what you want. Templates would be, except they don't have any compile-time string handling.

Usually, when people want to mix numeric bytes and string literals in the same char-array sequence, they use a string literal but use hex character escapes such as \xFF.


I might have found a way to do what i want though it isn't directly what I wanted, but it likely has the same effect.
First consider two following classes:

template <size_t size>
class Cont{
 public:
  char charArray[size];
};
template <size_t size>
class ArrayToUse{
 public:
  Cont<size> container;
  inline ArrayToUse(const Cont<size+1> & input):container(reinterpret_cast<const Cont<size> &>(input)){}
};

Before proceeding, you might want to go here and take a look at constant expression constructors and initialization types.
Now look at following code:

const Cont<12> container={"hello world"};
ArrayToUse<11> temp(container);
char (&charArray)[11]=temp.container.charArray;

Finally initializer text is written between two double quotations.

0

精彩评论

暂无评论...
验证码 换一张
取 消