如何使用UTF-8在C ++中,转换工作从其他编码成UTF-8(How to work with U

2019-09-01 02:28发布

我不知道如何解决:

试想一下,我们有4名网站:

  • 答:UTF-8
  • B:ISO-8859-1
  • C:ASCII
  • d:UTF-16

我用C ++编写程序执行以下操作:它下载一个网站,并对其进行解析。 但它必须了解的内容。 我的问题是不是该用ASCII字符做过类似的分析">""<"

问题是,该方案应找出网站的文本的所有单词。 一个字是字母数字字符的任意组合。 然后我把这些话给服务器。 数据库和网络的前端使用的是UTF-8。 所以我的问题是:

  • 我怎么能转换“任何”(或最常用)的字符编码成UTF-8?
  • 我怎样才能在C ++ UTF-8字符串的工作? 我认为wchar_t不起作用,因为它是2个字节长。 码点的UTF-8是多达4个字节长...
  • 是否有类似的功能isspace() isalnum() strlen() tolower()这样的UTF-8字符串?

请注意:我没有做任何输出(如std::cout在C)++。 只是过滤掉字,并将其发送到服务器。

我知道UTF8-CPP,但它没有is*()函数。 当我读,它不会转换其他字符编码成UTF-8。 只有从UTF-*为UTF-8。

编辑:我忘了说,该方案具有可移植:在Windows,Linux,...

Answer 1:

我怎么能转换“任何”(或最常用)的字符编码成UTF-8?

ICU (Unicode的国际组件)是这里的解决方案。 人们普遍认为是在支持Unicode的最后发言权。 即使Boost.Locale和Boost.Regex使用它时,它涉及到Unicode。 见我的多莉西顿的回答评论,为什么我建议直接用ICU,而不是包装(如升压)。

您创建一个给定的编码转换器...

#include <ucnv.h>

UConverter * converter;
UErrorCode err = U_ZERO_ERROR;
converter = ucnv_open( "8859-1", &err );
if ( U_SUCCESS( error ) )
{
    // ...
    ucnv_close( converter );
}

...然后使用的UnicodeString类作为appripriate。

我认为wchar_t的不起作用,因为它是2个字节长。

的大小wchar_t是实现定义的。 AFAICR,视窗是2字节(UCS-2 / UTF-16,这取决于Windows版本),Linux是4字节(UTF-32)。 在任何情况下,由于标准没有定义的Unicode语义wchar_t ,使用它是不可移植的猜测。 不用猜,使用ICU。

有没有像isspace为函数(),字符isalnum(),strlen的(),tolower的()这样的UTF-8字符串?

不符合他们的UTF-8编码,但你不使用内部反正。 UTF-8是良好的外部表示,但在内部UTF-16或UTF-32是更好的选择。 上述功能确实存在Unicode代码点(即,UChar32); REF。 uchar.h 。

请注意:我不使用C做任何输出(比如std ::法院)++。 只是过滤掉字,并将其发送到服务器。

检查的BreakIterator 。

编辑:我忘了说,该方案具有可移植:在Windows,Linux,...

如果我没有说,它已经, 确实使用ICU,并保存自己吨的麻烦。 即使乍一看似乎有点重量级的,它最好的实现在那里,这极为便携(使用它在Windows,Linux和AIX我自己),你在项目中一次又一次又一次用它来来,所以投资在学习它的API不浪费时间。



Answer 2:

不知道这是否会给你你正在寻找的一切,但它可能会有点帮助。 您是否尝试过寻找:

1)Boost.Locale库? Boost.Locale在升压1.48(2011年11月15日),使其更容易从转换并为UTF8 / 16发布

下面是从文档一些方便的例子:

string utf8_string = to_utf<char>(latin1_string,"Latin1");
wstring wide_string = to_utf<wchar_t>(latin1_string,"Latin1");
string latin1_string = from_utf(wide_string,"Latin1");
string utf8_string2 = utf_to_utf<char>(wide_string);

2)或在转换是的C ++ 11部分?

#include <codecvt>
#include <locale>
#include <string>
#include <cassert>

int main() {
  std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
  std::string utf8 = convert.to_bytes(0x5e9);
  assert(utf8.length() == 2);
  assert(utf8[0] == '\xD7');
  assert(utf8[1] == '\xA9');
}


Answer 3:

我怎样才能在C ++ UTF-8字符串的工作? 我认为wchar_t的不起作用,因为它是2个字节长。 码点的UTF-8是多达4个字节长...

这是很容易,有一个名为项目tinyutf8 ,这是一个简易替换 std::string / std::wstring

然后,用户可以上优雅码点操作,同时其表示在总是被编码char秒。


我怎么能转换“任何”(或最常用)的字符编码成UTF-8?

你可能想看看std::codecvt_utf8和simlilar模板从<codecvt> (C ++ 11)。



Answer 4:

UTF-8是使用用于利用所述第8位的非ASCII(7位代码)多个字节的编码。 因此,你不会找到'\''/'多字节序列内。 和isdigit作品(虽然不是阿拉伯语和其他数字)。

这是ASCII的一个超集,可以容纳所有Unicode字符,所以肯定有字符和字符串使用。

检查的HTTP标头(不区分大小写); 他们是在ISO 8859,并先于一个空行,然后HTML内容。

Content-Type: text/html; charset=UTF-8

如果不出现,也有可能是

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">      <!-- HTML5 -->

ISO-8859-1是拉丁文1,你可能做的更好从Windows 1252转换,在Windows Latin-1的扩展使用0x80的 - 为0xBF对于一些特殊的字符,如逗号报价和这样。 虽然指定了ISO-8859即使在MacOS浏览器会理解这些。

转换库:通过@syam提到alread。

转变

让我们不要考虑UTF-16。 一个可以读取头,并开始直到该字符集的单字节字符元声明。

从单字节编码为UTF-8的转化可以通过表格发生。 例如使用Java生成:一个const char* table[]索引由炭。

table[157] = "\xEF\xBF\xBD";


public static void main(String[] args) {
    final String SOURCE_ENCODING = "windows-1252";
    byte[] sourceBytes = new byte[1];
    System.out.println("    const char* table[] = {");
    for (int c = 0; c < 256; ++c) {
        String comment = "";
        System.out.printf("       /* %3d */ \"", c);
        if (32 <= c && c < 127) {
            // Pure ASCII
            if (c == '\"' || c == '\\')
                System.out.print("\\");
            System.out.print((char)c);
        } else {
            if (c == 0) {
                comment = " // Unusable";
            }
            sourceBytes[0] = (byte)c;
            try {
                byte[] targetBytes = new String(sourceBytes, SOURCE_ENCODING).getBytes("UTF-8");
                for (int j = 0; j < targetBytes.length; ++j) {
                    int b = targetBytes[j] & 0xFF;
                    System.out.printf("\\x%02X", b);
                }
            } catch (UnsupportedEncodingException ex) {
                comment = " // " + ex.getMessage().replaceAll("\\s+", " "); // No newlines.
            }
        }
        System.out.print("\"");
        if (c < 255) {
            System.out.print(",");
        }
        System.out.println();
    }
    System.out.println("    };");
}


文章来源: How to work with UTF-8 in C++, Conversion from other Encodings to UTF-8