9

假设我已经初始化了一个 char 数组:

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

而且我还对字符串文字进行了以下初始化:

char stringLiteral[]="hello world";

第一个数组和第二个字符串的内容之间的唯一区别是第二个字符串的末尾有一个空字符。

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

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

我应该补充一点,当我想要一个 char 数组时,很明显我不想将它与依赖于字符串文字的函数一起使用,而且没有任何使用字符串文字的功能是在我的考虑范围内。

我很感谢你的回答。

4

5 回答 5

9

在 C 中允许如下声明数组,这将在不复制终止的情况下对其进行初始化'\0'

char c[3] = "foo";

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

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

于 2010-07-09T21:07:20.563 回答
3

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

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

于 2010-07-09T20:55:25.273 回答
1

litb 有技术上正确的答案

至于意见 - 我说只是忍受额外的'\ 0'的'浪费'。如此多的错误是代码期望终止 null 而不是的结果(这个建议似乎直接违背了我在一两天前给出的关于不要将整个缓冲区归零的其他建议。我声称没有矛盾——我仍然主张用 null 终止缓冲区中的字符串)。

如果你真的不能使用 '\0' 终止符,因为你正在处理的数据结构中的一些语义,比如它可能是一些更大的打包结构的一部分,你总是可以自己初始化数组(我think 的效率应该不低于编译器可能为您完成的工作):

#define MY_STRING_LITERAL "hello world"

char stringLiteral[sizeof(MY_STRING_LITERAL) - 1];

memcpy( stringLiteral, MY_STRING_LITERAL, sizeof(stringLiteral));
于 2010-07-09T23:54:26.733 回答
0

我可能已经找到了一种方法来做我想做的事,虽然它不是我想要的,但它可能具有相同的效果。
首先考虑以下两个类:

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)){}
};

在继续之前,您可能想去这里看看常量表达式构造函数和初始化类型。
现在看下面的代码:

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

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

于 2010-07-11T10:19:06.523 回答
0

基本答案是绝大多数 char 数组都是字符串 - 在 C 中,字符串以空值结尾。C++ 继承了该约定。即使不需要那个空值,大多数时候把它留在那里也不是问题。

宏功能不够强大,无法满足您的需求。模板将是,除了它们没有任何编译时字符串处理。

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

于 2010-07-09T21:02:30.577 回答