将字符串转换为UTF-8转义序列 在我的C++程序中,我想把这样的字符串转换成: abc €

将字符串转换为UTF-8转义序列 在我的C++程序中,我想把这样的字符串转换成: abc €,c++,unicode,utf-8,cross-platform,C++,Unicode,Utf 8,Cross Platform,到UTF-8转义序列: abc%20%E2%82%AC 我需要它独立于平台!我发现的所有解决方案都只适用于windows。一定有解决方案吧?在C++11之前,标准中没有强制支持UTF-8 这里有两个步骤: 转换为UTF-8(除非已经在UTF-8中) URL转义结果(更新:James Kanze涵盖此部分) 假设您知道输入字符串使用[*]的字符编码,那么这两种代码都不太难为自己编写。这意味着其他人以前做过,你不需要自己写。如果您单独搜索它们,您可能会更幸运地为每个步骤找到独立于平台的代码 注

到UTF-8转义序列:

abc%20%E2%82%AC

我需要它独立于平台!我发现的所有解决方案都只适用于windows。一定有解决方案吧?

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

这里有两个步骤:

  • 转换为UTF-8(除非已经在UTF-8中)
  • URL转义结果(更新:James Kanze涵盖此部分)
假设您知道输入字符串使用[*]的字符编码,那么这两种代码都不太难为自己编写。这意味着其他人以前做过,你不需要自己写。如果您单独搜索它们,您可能会更幸运地为每个步骤找到独立于平台的代码

注意,有两种不同的URL转义空格字符的方法,一种是
+
,另一种是
%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转义UTF-8

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

这里有两个步骤:

  • 转换为UTF-8(除非已经在UTF-8中)
  • URL转义结果(更新:James Kanze涵盖此部分)
假设您知道输入字符串使用[*]的字符编码,那么这两种代码都不太难为自己编写。这意味着其他人以前做过,你不需要自己写。如果您单独搜索它们,您可能会更幸运地为每个步骤找到独立于平台的代码

注意,有两种不同的URL转义空格字符的方法,一种是
+
,另一种是
%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转义UTF-8

    • 这对我来说似乎相当简单。您的字符串是一个 字节。某些字节值(实际上是最多的,但不是最常见的) 不允许,应替换为三个字符 序列
      '%'
      后跟表示字节的两个十六进制字符 价值比如:

      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;
      }
      
      std::string
      toEscaped(标准::字符串常量和原始)
      {
      std::字符串结果;
      for(std::string::const_迭代器iter=original.begin();
      iter!=original.end();
      ++国际热核聚变实验堆(iter){
      允许的静态布尔常量[]=
      {
      //定义256个条目。。。
      };
      如果(允许[静态熔铸(*iter)]){
      结果+=*iter;
      }否则{
      静态字符常量hexChars[]=“0123456789ABCDEF”;
      结果+='%';
      结果+=六角体[(*iter>>4)和0x0F];
      结果+=六角体[(*iter)和0x0F];
      }
      }
      返回结果;
      }
      

      我们应该做到这一点

      这对我来说似乎相当简单。您的字符串是一个 字节。某些字节值(实际上是最多的,但不是最常见的) 不允许,应替换为三个字符 序列
      '%'
      后跟表示字节的两个十六进制字符 价值比如:

      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;
      }
      
      std::string
      toEscaped(标准::字符串常量和原始)
      {
      std::字符串结果;
      for(std::string::const_迭代器iter=original.begin();
      iter!=original.end();
      ++国际热核聚变实验堆(iter){
      允许的静态布尔常量[]=
      {
      //定义256个条目。。。
      };
      如果(允许[静态熔铸(*iter)]){
      结果+=*iter;
      }否则{
      静态字符常量hexChars[]=“0123456789ABCDEF”;
      结果+='%';
      结果+=六角体[(*iter>>4)和0x0F];
      结果+=六角体[(*iter)和0x0F];
      }
      }
      返回结果;
      }
      

      我们应该做到这一点

      对于独立于平台的功能丰富的Unicode处理,“事实上”的标准库是许多财富500强公司和开源项目使用的ICU。。。 该许可证是开源的,便于在商业开发中使用

      如果你只是想使用一些简单的转换,那就太过分了

      如果你只需要一个简单的便携式UTF-8C++库,你可以尝试


      hth

      对于平台无关的功能丰富的Unicode处理,“事实上”的标准库是i