原始字符串文字和文件编码

时间:2014-01-30 15:33:21

标签: c++ c++11 string-literals rawstring

C ++ 11引入了raw string literals,它可以非常有用于表示带引号的字符串,带有许多特殊符号的文字,如Windows文件路径,正则表达式等......

std::string path = R"(C:\teamwork\new_project\project1)"; // no tab nor newline!
std::string quoted = R"("quoted string")";
std::string expression = R"([\w]+[ ]+)";

此原始字符串文字也可以与编码前缀(u8uUL)组合使用,但是,如果未指定编码前缀,文件编码是否重要?让我们假设我有这段代码:

auto message = R"(Pick up a card)";         // raw string 1
auto cards = R"()"; // raw string 2

如果我可以编写并存储上面的代码,很明显我的源代码被编码为unicode,所以我想知道:

  • raw string 1是unicode文字吗? (尽管它只使用ASCII字符),换句话说,原始字符串是否继承了编写文件的编码,或者编译器自动检测到不管文件编码如何都不需要unicode?
  • U上的编码前缀raw string 2是否有必要将其视为unicode文字或由于其内容和/或源文件编码而自动为unicode?

感谢您的关注。

编辑:

在ideone.com上测试上面的代码并打印解码类型的messagecards变量,它会输出char const*

template<typename T> std::string demangle(T t)
{
    int status;
    char *const name = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
    std::string result(name);
    free(name);
    return result;
}

int main()
{
    auto message = R"(Pick up a card)";
    auto cards = R"()";

    std::cout
        << "message type: " << demangle(message) << '\n'
        << "cards type: " << demangle(cards) << '\n';

    return 0;
}

输出:

  

message type: char const*

     

cards type: char const*

这甚至比我想象的更奇怪,我确信类型会是wchar_t(即使没有L前缀)。

2 个答案:

答案 0 :(得分:1)

是的,重要的是,即使是编译你的来源。如果你使用-finput-charset=UTF-16,你将需要使用像gcc这样的somenthing进行编译(同样的事情应该适用于VS)。

但是我IHMO,在你的代码中有一些更基本的东西需要考虑。例如,std::stringchar的容器,大小为1个字节。例如,如果您正在处理UTF-16,则需要2个字节,因此(尽管有“手动转换”),您至少需要wchar_t(std :: wstring)(或者,更安全char16_t,在C++11中更安全。

因此,要使用Unicode,您需要一个容器,并且需要一个编译环境来处理您的Unicode编码源。

答案 1 :(得分:1)

原始字符串文字会更改处理转义的方式,但不会更改编码的处理方式。原始字符串文字仍然将其内容从源编码转换为以适当的执行编码生成字符串。

字符串文字的类型和相应的执行编码完全由前缀决定。仅R总是在窄执行编码中生成char字符串。如果源是UTF-16(并且编译器支持UTF-16作为源编码),则编译器将字符串文字内容从UTF-16转换为窄执行编码。