C++ 以类似于初始化字符串文字的方式初始化字符数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3216462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:21:09  来源:igfitidea点击:

initializing char arrays in a way similar to initializing string literals

c++stringarraysinitializationliterals

提问by Pooria

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?

当涉及初始化 char 数组时,是否有宏或其他东西允许我们将初始化文本放在两个双引号之间,但数组没有获得额外的空终止字符?

It just doesn't make sense to me that when a terminating null character 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.

对我来说,当不需要终止空字符时,我们应该使用第一次提到的初始化语法并为初始化文本中的每个字符写两个单引号,以及分隔字符的 virgule 标记,这对我来说没有意义。

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.

我应该补充一点,当我想要一个 char 数组时,很明显我不想将它与依赖字符串文字的函数一起使用,以及使用字符串文字结果的所有功能都不是进入我的考虑。

I'm thankful for your answers.

我很感谢你的回答。

采纳答案by Pooria

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 hereand 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.

最后初始化文本写在两个双引号之间。

回答by Johannes Schaub - litb

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

在 C 中允许如下声明数组,这将初始化它而不复制终止 '\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

但它在 C++ 中是非法的。我不知道允许它用于 C++ 的技巧。C++ 标准进一步说

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.

基本原理:当这些未终止的数组由标准字符串例程操作时,可能会发生重大灾难。
对原始特征的影响:删除语义明确的特征。
转换难度:语义转换。必须将数组声明为大一个元素以包含终止于 '\0' 的字符串。
使用范围:很少。这种数组初始化风格被视为糟糕的编码风格。

回答by hkaiser

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.

没有办法做你想做的事。初始化数组的第一种方法为每个字符指定单独的初始值设定项,这允许显式省略 '\0'。第二种是从字符串初始化字符数组,在 C/C++ 中,字符串总是以空字符结尾。

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

编辑:更正:“字符指针”-->“字符数组”

回答by Michael Burr

litb has the technically correct answer.

litb 有技术上正确的答案

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).

至于意见 - 我说只是忍受额外的“\ 0”的“浪费”。如此多的错误是代码期望终止 null 而不是的结果(这个建议似乎直接与我一两天前给出的关于不打扰整个缓冲区为零的其他建议相反。我声称没有矛盾 - 我仍然主张空终止缓冲区中的字符串)。

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):

如果你真的无法忍受 '\0' 终止符,因为你正在处理的数据结构中有一些语义,比如它可能是一些更大的压缩结构的一部分,你总是可以自己初始化数组(我认为应该不低于编译器可能为您所做的效率):

#define MY_STRING_LITERAL "hello world"

char stringLiteral[sizeof(MY_STRING_LITERAL) - 1];

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

回答by Steve314

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.

基本答案是绝大多数字符数组都是字符串——在 C 中,字符串以空字符结尾。C++ 继承了这个约定。即使不需要 null,大多数情况下,将它留在那里也不是问题。

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.

通常,当人们想要在同一个字符数组序列中混合数字字节和字符串文字时,他们使用字符串文字但使用十六进制字符转义,例如\xFF.