将字符串转换为UTF-8转义序列

时间:2011-11-10 10:36:45

标签: c++ unicode utf-8 cross-platform

在我的C ++程序中,我想转换一个std:string,如下所示:

abc €

到UTF-8转义序列:

abc%20%E2%82%AC

我需要它与平台无关!我发现的所有解决方案都只适用于Windows。那里必须有一个解决方案吗?

3 个答案:

答案 0 :(得分:4)

对我而言似乎相当简单。你的字符串是一系列的 字节。某些字节值(大多数,实际上,但不是最常见的) 是不允许的,应该用三个字符替换 序列'%'后跟两个表示字节的十六进制字符 值。如下所示:

std::string
toEscaped( std::string const& original )
{
    std::string results ;
    for ( std::string::const_iterator iter = original.begin();
            iter != original.end();
            ++ iter ) {
        static bool const allowed[] =
        {
            //  Define the 256 entries...
        };
        if ( allowed[static_cast<unsigned char>(*iter)] ) {
            results += *iter;
        } else {
            static char const hexChars[] = "0123456789ABCDEF";
            results += '%';
            results += hexChars[(*iter >> 4) & 0x0F];
            results += hexChars[(*iter     ) & 0x0F];
        }
    }
    return results;
}

应该做的伎俩。

答案 1 :(得分:3)

在C ++ 11之前,标准中没有强制要求支持UTF-8。

这里有两个步骤:

  • 转换为UTF-8(除非它已经是UTF-8)
  • URL-escape结果(更新:James Kanze涵盖此部分)

假设您知道输入字符串使用[*]的字符编码,那么它们都不是特别难以自行编写。这意味着其他人以前做过,你不应该自己写。如果您单独搜索它们,您可能会更好地为每个步骤找到与平台无关的代码。

请注意,对于空格字符进行网址转义有两种不同的方式:+%20。您的示例使用%20,因此如果这对您很重要,那么请不要意外地使用执行另一个的URL转义例程。

[*]它不是ISO-Latin-1,因为它没有欧元符号[**],但它可能是Windows CP-1252。

[**]除非最近添加了。无论如何,您的示例将欧元符号编码为UTF-8字节0xE2 0x82 0xAC,它代表Unicode代码点0x20AC,而不是CP1252中的代码点0x80。因此,如果它最初是一个单字节编码,那么很明显,在此过程中已经应用了智能的单字节到unicode代码点转换。你可以说有三个步骤:

  • std::string转换为Unicode代码点(取决于输入编码)。
  • 将Unicode转换为UTF-8
  • URL-escape UTF-8

答案 2 :(得分:2)

对于平台无关的功能丰富的Unicode处理“事实上的”标准库是许多财富500强公司和开源项目使用的ICU ...... 该许可证是开源的,友好的,可用于商业开发

如果您只想使用一些简单的转换,那可能会有点过分......

http://site.icu-project.org

如果您只需要一个简单的便携式utf-8 c ++库,可以试试http://utfcpp.sourceforge.net

HTH