如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N>

Posted

技术标签:

【中文标题】如何使用省略尾随 \'\\0\' 的字符串文字初始化 std::array<char, N>【英文标题】:How to initialize a std::array<char, N> with a string literal omitting the trailing '\0'如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N> 【发布时间】:2015-11-02 18:16:27 【问题描述】:

我有一个文件结构,其中固定长度的字符串没有尾随零。 如何将字段初始化为 std::array 而不尾随零:

#pragma pack(push, 1)
struct Data 
    // Compiles, but it has an undesired '\0':
    std::array<char, 6> undesired_number"12345";
    // Does not compile:
    std::array<char, 5> number"12345"; // stripping '\0'
;
#pragma pack(pop)

【问题讨论】:

什么是编译器错误?不兼容的类型?恐怕基于字符串文字根本不可能。 为什么一定要用字符串字面量来初始化呢? @Barmar 只是为了方便 由于字符串文字总是附加'\0' 或等价物,我的赌注是一些中间的constexpr/template 魔法,它会采用文字并去掉零并返回一个截断的值。但是它可能有问题,因为您不能修改字符串文字。也许常量表达式的例外允许它。 你可以制作一个用户定义的文字 【参考方案1】:

制作辅助函数

template <std::size_t N, std::size_t ... Is>
constexpr std::array<char, N - 1>
to_array(const char (&a)[N], std::index_sequence<Is...>)

    return a[Is]...;


template <std::size_t N>
constexpr std::array<char, N - 1> to_array(const char (&a)[N])

    return to_array(a, std::make_index_sequence<N - 1>());

然后

struct Data 
    std::array<char, 5> numberto_array("12345"); // stripping '\0'
;

Demo

【讨论】:

我想知道这是否会编译成文字的一个副本,或者两个,一个带有终止符,一个没有。 @luk32,取决于编译器和优化设置。例如,带有 O3 的 g++ 根本没有文字。 在获得make_index_sequence 并更改为std::array&lt;char, 5&gt; number = to_array("12345"); 后与C++11 很好地配合 @VioletGiraffe: std::array 主要是struct T data[N]; ;,所以在聚合初始化时,第一个括号是类array,第二个是它的data 成员。 (一对可以省略,但编译器可能会警告“缺少”大括号)。 @303:使用默认可初始化类型,例如char,您确实可以使用 for-range(即使从 C++14 开始(constexpr 函数中允许使用 for-range,并且std::array 的方法标记为 constexpr))。您不能使用 for-range 初始化,只能分配/复制,这对 char 来说很好。【参考方案2】:

字符串文字以 NUL 结尾的,在 C++ 中(与 C 不同),您不能通过提供 Length - 1 大小来取消它;因此它不能直接完成,同时考虑到array内部是T[N]

【讨论】:

标准不要求 array 在内部是 T[N]。对于N &gt; 0 的情况,有些人认为应该这样做

以上是关于如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N>的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止GCC从obj文件中的字符串文字中删除尾随换行符?

正则表达式匹配标签内容,同时省略前导和尾随空格

如何使用正则表达式删除尾随空格?

如何使用正则表达式删除尾随空格?

您可以在 JSON 对象中使用尾随逗号吗?

C语言编程:输入字符串s,将s中的前导空格和尾随空格删去,中间连续多个空格缩减