首页 > 解决方案 > 包含零的字符串初始化-> 编译器错误或预期行为?

问题描述

我尝试定义一些硬编码的 utf 序列。

喜欢

    static std::string const cUTF_16_BE_BOM = "\xFE\xFFTest";
    static std::string const cUTF_16_LE_BOM = "\xFF\xFETest";
    static std::string const cUTF_8_BOM     = "\xEF\xBB\xBFTest";
    static std::string const cUTF_32_BE_BOM = "\x00\x00\xFE\xFFTest";
    static std::string const cUTF_32_LE_BOM = "\xFF\xFE\x00\x00Test";
    static std::string const cUTF_7_BOM     = "\x2B\x2F\x76\x38\x2DTest";

但是 cUTF_32_BE_BOM 和 cUTF_32_LE_BOM 在第一种情况下会产生一个空字符串,而在第二种情况下会产生一个长度为 2 的字符串。

c++ 字符串不是能够在知道其实际大小的同时处理其中的多个 '\0' 字符吗?我希望 strlen 返回 0 和 2 作为长度或输出流仅在第一个 '\0' 之前使用。但是不按照书面代码进行初始化在我看来有点奇怪。

标签: c++stringutf

解决方案


这些将std::string使用 : 调用构造函数,const char*长度已经丢失,并且调用strlen( std::char_traits<char>::length) 的等价物来获取大小。

通常,您会使用std::string_literals::operator""s不丢失字符,但这在范围内'\0'可能不可行。::它看起来像这样:

using namespace std::string_literals;
static std::string const cUTF_32_BE_BOM = "\x00\x00\xFE\xFFTest"s;

您还可以调用带有一个const char*和一个长度参数的构造函数:

static std::string const cUTF_32_BE_BOM("\x00\x00\xFE\xFFTest", 8);

// Or without hardcoding the size
static std::string const cUTF_32_BE_BOM("\x00\x00\xFE\xFFTest", sizeof("\x00\x00\xFE\xFFTest")-1);

// Or without copying the string
template<std::size_t N>
std::string make_string_from_literal(const char(&s)[N]) {
    return std::string(s, N-1);  // -1 for last '\0' character
}

static std::string const cUTF_32_BE_BOM = make_string_from_literal("\x00\x00\xFE\xFFTest");

推荐阅读