字符串仪,没有逃脱零字符

String-literals without escaping null-character

本文关键字:逃脱 字符 字符串      更新时间:2023-10-16

当我构建一个函数时,它给出了nibble(4位(的十六进制表示,我查看了二进制文件,以使数字的外观可口即使没有使用。

const char digits[] = "0123456789abcdef";

我知道您可以以数组的形式编写它:

const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

但这需要一段时间才能为其他数字更多数字系统编写和使用更多的磁盘空间。但是,有什么方法可以将其写为字面意思,但是没有零字符?

(我正在使用-std=c++14的Clang(

在C中,您可以写

const char digits[16] = "0123456789abcdef";

实际上在数组初始化中定义的C中支持这:

如果已知数组的大小,则可能比 字符串文字,在这种情况下,终止null字符为 忽略:char str[3] = "abc"; // str has type char[3] and holds 'a', 'b', 'c'

对于C ,我没有直接的方式;但是,一个人可能会如下:

char digits_t[16] = "0123456789abcde";
digits_t[15]='f';    
const char* digits = digits_t;

我不知道为什么要做这样的事情,但是如果您可以应付使用编译器扩展程序,Clang和GCC将让您编写一个模板的用户定义的文字将砍掉尾声的操作员:

template <typename CharT, std::size_t N>
struct string_literal {
    static constexpr std::size_t size = N;
    const CharT str[N];
};
template <typename CharT, CharT... Str>
constexpr string_literal<CharT, sizeof...(Str)> operator"" _lit()
{
    return {{ Str... }};
}
int main()
{
    constexpr auto s = "test"_lit;
    static_assert(s.size == 4);
    static_assert(s.str[0] == 't'); // etc
}

(返回std::array<const char, N>是另一个选择。(

我不知道这是否是您所追求的,但是我并不真正理解诚实的动机 - 即使在70年代,C的设计师也不必担心"浪费"字符串中的单个字节。

这可能是过分的,但是如果使用 std::array是可以接受的,那么您可以使用constexpr函数从字符串中静态地构建一个:

#include <array>
#include <iostream>
// A type-level list of indices.
template <size_t... Xs>
struct indices { using type = indices<Xs..., sizeof...(Xs)>; };
// Generate indices from 0 to N.
template <std::size_t N>
struct upto { using type = typename upto<N - 1>::type::type; };
template <>
struct upto<0> { using type = indices<>; };
// Make an array by assigning each character
// from the corresponding index in the source.
template <std::size_t... X, typename A = std::array<char, sizeof...(X)>>
constexpr A make_array(char const *const source, const indices<X...>&) {
    return A{{source[X]...}};
}
// A convenience function that deduces the size.
template <std::size_t N>
constexpr std::array<char, N - 1> string_constant(char const (&data)[N]) {
    return make_array(&data[0], typename upto<N - 1>::type{});
}
int main() {
    constexpr auto s = string_constant("123456");
    std::cout << sizeof(s) << 'n';
}

现在sizeof(s)6,如果您查看生成的汇编,则字符串文字存储为.ascii,而不是.asciz,因此没有尾随的null字符。您可以使用std::array的成员函数,例如size()begin()end(),并且可以将&s[0]施放到const char *直接访问字符数据。