Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ UNICODE、UTF-8和Windows mess_C++_C_Windows_Unicode_Utf 8 - Fatal编程技术网

C++ UNICODE、UTF-8和Windows mess

C++ UNICODE、UTF-8和Windows mess,c++,c,windows,unicode,utf-8,C++,C,Windows,Unicode,Utf 8,我正在尝试在Windows中实现文本支持,并打算以后也转向Linux平台。以统一的方式支持国际语言是很理想的,但考虑到这两个平台,这似乎并不容易实现。我花了相当多的时间阅读UNICODE、UTF-8(和其他编码)、widechars等,以下是我到目前为止理解的内容: UNICODE作为标准,描述了可映射的字符集及其出现的顺序。我将其称为“what”:UNICODE指定可用的内容 UTF-8(和其他编码)指定如何:如何以二进制格式表示每个字符 现在,在windows上,他们最初选择了UCS-2编码

我正在尝试在Windows中实现文本支持,并打算以后也转向Linux平台。以统一的方式支持国际语言是很理想的,但考虑到这两个平台,这似乎并不容易实现。我花了相当多的时间阅读UNICODE、UTF-8(和其他编码)、widechars等,以下是我到目前为止理解的内容:

UNICODE作为标准,描述了可映射的字符集及其出现的顺序。我将其称为“what”:UNICODE指定可用的内容

UTF-8(和其他编码)指定如何:如何以二进制格式表示每个字符

现在,在windows上,他们最初选择了UCS-2编码,但这不符合要求,所以UTF-16就是他们所拥有的,必要时也是多字符的

这就是德莱玛:

  • Windows内部仅支持UTF-16,因此,如果您想支持国际字符,则必须将其转换为widechar版本,以便相应地使用操作系统调用。似乎不支持使用多字节UTF-8字符串调用CreateFileA()之类的东西,并使其看起来正常。这是正确的吗
  • 在C语言中,有一些支持多字节的函数(_mbscat、_mbscpy等),但是在windows上,这些函数的字符类型定义为无符号字符*。鉴于_mbs系列函数不是一个完整的集合(例如,没有将多字节字符串转换为长字符串的_mbstol),您不得不使用一些char*版本的运行时函数,这会导致编译器问题,因为这些函数之间的有符号/无符号类型不同。有人用过吗?你只是做了一大堆的铸造来避免错误吗
  • 在C++中,STD::string有迭代器,但是这些是基于CARYL类型,而不是基于代码点。因此,如果我在std::string::iterator上执行一个+,我将得到下一个字符类型,而不是下一个代码点。类似地,如果调用std::string::operator[],则会得到对char_类型的引用,该类型很可能不是完整的代码点。那么,如何按代码点迭代std::string呢?(C具有_mbsinc()函数)
  • Windows内部仅支持UTF-16,因此,如果您想支持国际字符,则必须将其转换为widechar版本,以便相应地使用操作系统调用。似乎不支持使用多字节UTF-8字符串调用CreateFileA()之类的东西,并使其看起来正常。这是正确的吗
  • 是的,没错。
    *A
    函数变量根据当前活动的代码页(在美国和西欧的大多数计算机上是Windows-1252,但通常可以是其他代码页)解释字符串参数,并将其转换为UTF-16。有一个UTF-8代码页,但是没有一种方法可以通过编程设置活动代码页(可以获取活动代码页,但没有相应的
    SetACP

  • 在C语言中,有一些支持多字节的函数(_mbscat、_mbscpy等),但是在windows上,这些函数的字符类型定义为无符号字符*。鉴于_mbs系列函数不是一个完整的集合(例如,没有将多字节字符串转换为长字符串的_mbstol),您不得不使用一些char*版本的运行时函数,这会导致编译器问题,因为这些函数之间的有符号/无符号类型不同。有人用过吗?你只是做了一大堆的铸造来避免错误吗
  • 根据我的经验,
    mbs*
    函数族几乎从未使用过。除了
    mbstowcs
    mbsrtowcs
    mbsinit
    ,这些功能不是标准的C

  • 在C++中,STD::string有迭代器,但是这些是基于CARYL类型,而不是基于代码点。因此,如果我在std::string::iterator上执行一个+,我将得到下一个字符类型,而不是下一个代码点。类似地,如果调用std::string::operator[],则会得到对char_类型的引用,该类型很可能不是完整的代码点。那么,如何按代码点迭代std::string呢?(C具有_mbsinc()函数)
  • 我认为这是解码多字节字符串的单个代码点的最佳选择

    总的来说,我认为跨平台Unicode兼容性的最佳策略是在UTF-8内部使用单字节字符。当需要调用Windows API函数时,请将其转换为UTF-16,并始终调用
    *W
    变量。大多数非Windows平台已经使用UTF-8,因此使用UTF-8非常简单

  • 对。您将为Windows API调用将UTF-8转换为UTF-16

  • 大多数情况下,您将对UTF-8使用常规字符串函数--
    strlen
    strcpy
    (ick),
    snprintf
    strtol
    。它们可以很好地处理UTF-8字符。对UTF-8使用
    char*
    ,否则您将不得不强制转换所有内容

    请注意,下划线版本(如
    \u mbstowcs
    )不是标准版本,它们的命名通常不带下划线,如
    mbstowcs

  • 很难给出实际希望在Unicode字符串上使用
    运算符[]
    的示例,我的建议是远离它。类似地,对字符串进行迭代的用途也很少:

    • 如果您正在解析一个字符串(例如,字符串是C或JavaScript代码,可能您需要语法高亮显示),那么您可以逐字节完成大部分工作,而忽略多字节方面

    • 如果您正在执行搜索,您还将逐字节执行此操作(但请记住先进行规范化)<