不以nul结尾的常量字符串文字

constant string literal without terminating nul

本文关键字:字符串 文字 常量 nul 结尾 不以      更新时间:2023-10-16

有没有一些技巧可以定义一个没有尾随''字符的常量字符串文字?

#define ARRAY_LEN(array) (sizeof(array)/sizeof((array)[0]))
static const char c_seqence[] = "___----__--_-_";

所以使用ARRAY_LEN(c_seqence)返回没有''的实际序列长度?不应生成运行时ovearhead。显然,由于可读性更好,类似字符串的表示被首选为字符数组{'_','_',...}初始化。

C解决方案是首选的,但也可能是一些C++解决方案,只要它们不依赖于C++11特性,就可能很有趣。

有没有一些技巧可以定义一个不带尾随"\0"字符?

在C中,如果将字符数组的大小指定为比字符串文字初始值设定项的大小小一,则它将不会有尾随的null字符。你可以这样做:

static const char c_seqence[ARRAY_LEN("___----__--_-_")-1] = "___----__--_-_";

当然,为了避免在同一行中两次指示字符串文字,您可能需要定义一个宏来执行此操作:

#define MAKE_STR_LITERAL(n, l) static const char n[ARRAY_LEN(l)-1] = l

你可以这样使用它:

MAKE_STR_LITERAL(c_seqence, "___----__--_-_");

注意

如中所述https://stackoverflow.com/a/4348188/2793118,该行为在标准的6.7.8节中(引用该答案):

§6.7.8p14

字符类型的数组可以由字符串初始化文字,可选地用大括号括起来。的连续字符字符串文字(如果有空间,或者如果阵列大小未知)初始化数组的元素。

注意2:原来这是一个只有C的东西。在C++中,它不会编译。另一个很好的例子说明了为什么人们不应该同时用C和C++来标记问题。

最简单的解决方案是更改数组长度宏以忽略后面的null:

#define ARRAY_LEN(array) (sizeof(array)/sizeof((array)[0]) - 1)

(在胁迫下发布:)

在C++11中,没有宏:

template <typename T, size_t n>
constexpr size_t array_length(const T (&)[n]) {
    return n;
}
template <typename T, size_t n>
constexpr size_t string_length(const T (&)[n]) {
    return n - 1;
}

我意识到这个问题明确地消除了C++11,但对于每个从搜索引擎中找到这个问题的人来说,这可能不是真的。