C Unicode:如何将C11标准修订版DR488修复程序应用于C11标准函数c16rtomb()? 问题:

C Unicode:如何将C11标准修订版DR488修复程序应用于C11标准函数c16rtomb()? 问题:,c,unicode,utf-8,utf-16,c11,C,Unicode,Utf 8,Utf 16,C11,如函数的C参考页中所述,c16rtomb,来自,在注释部分下: 在已发布的C11中,与将可变宽度多字节(如UTF-8)转换为可变宽度16位(如UTF-16)编码的mbrtoc16不同,该函数只能转换单个单元16位编码,这意味着它无法将UTF-16转换为UTF-8,尽管这是该函数的初衷。这已通过C11后缺陷报告得到纠正 在本文下面,C参考页提供了一个示例源代码,上面有以下句子: 注意:本例假设应用了缺陷报告488的修复程序 这句话意味着有一种方法可以使用DR488,并以某种方式“应用”C11标准函

如函数的C参考页中所述,
c16rtomb
,来自,在注释部分下:

在已发布的C11中,与将可变宽度多字节(如UTF-8)转换为可变宽度16位(如UTF-16)编码的
mbrtoc16
不同,该函数只能转换单个单元16位编码,这意味着它无法将UTF-16转换为UTF-8,尽管这是该函数的初衷。这已通过C11后缺陷报告得到纠正

在本文下面,C参考页提供了一个示例源代码,上面有以下句子:

注意:本例假设应用了缺陷报告488的修复程序

这句话意味着有一种方法可以使用DR488,并以某种方式“应用”C11标准函数的修复程序,
c16rtomb

我想知道如何应用GCC的修复程序。因为在我看来,修复已经应用于VisualStudio 2017 Visual C++,如V141../P>。 在GDB中调试代码时,GCC中的行为与DR488中的行为一致,如下所示:

第7.28.1节描述了功能c16rtomb()。特别是,它声明“当c16不是有效的宽字符时,会发生编码错误”。“宽字符”在第3.7.3节中定义为“可由wchar_t类型的对象表示的值,能够表示当前区域设置中的任何字符”该措辞似乎暗示,例如,对于常见情况(例如,定义uuu STDC_UTF_16_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.特别是,c16rtomb()将无法处理MBRTO16()生成的字符串

粗体文本是所描述的行为

源代码: GCC的输出:
在Linux中,您应该能够通过调用
setlocale(LC_ALL,“en_US.utf8”)来解决这个问题

榜样

此功能将执行以下操作,如中所述:

在当前语言环境中将UTF-16宽字符转换为多字节字符

POSIX文档与此类似<代码>\uuuu STD\uutf\u16\uuuu
在两个编译器中似乎都没有效果。它应该指定源代码的编码,应该是UTF16。它没有指定目标的编码


Windows文档似乎更不一致,因为它似乎暗示
setlocale
是必要的,或者转换为ANSI代码页是一个选项

当然有一种方法可以修复标准库函数:下载标准库的源代码,更改代码,构建并安装它。DR488没有补丁,只是一个文字补丁。必须有人把这些词翻译成代码。@immibis哦,这就是它的意思。我会调查的。谢谢,谢谢!我想我真的必须学习如何编译和构建gcc,并进行修改以匹配DR488,因为到目前为止还没有好的答案。
#include <stdio.h>
#include <uchar.h>

#define __STD_UTF_16__

int main() {
    char16_t* ptr_string = (char16_t*) u"我是誰";

    //C++ disallows variable-length arrays. 
    //GCC uses GNUC++, which has a C++ extension for variable length arrays.
    //It is not a truly standard feature in C++ pedantic mode at all.
    //https://stackoverflow.com/questions/40633344/variable-length-arrays-in-c14
    char buffer[64];
    char* bufferOut = buffer;

    //Must zero this object before attempting to use mbstate_t at all.
    mbstate_t multiByteState = {};

    //c16 = 16-bit Characters or char16_t typed characters
    //r = representation
    //tomb = to Multi-Byte Strings
    while (*ptr_string) {
        char16_t character = *ptr_string;
        size_t size = c16rtomb(bufferOut, character, &multiByteState);
        if (size == (size_t) -1)
            break;
        bufferOut += size;
        ptr_string++;
    }

    size_t bufferOutSize = bufferOut - buffer;
    printf("Size: %zu - ", bufferOutSize);
    for (int i = 0; i < bufferOutSize; i++) {
        printf("%#x ", +(unsigned char) buffer[i]);
    }

    //This statement is used to set a breakpoint. It does not do anything else.
    int debug = 0;
    return 0;
}
Size: 9 - 0xe6 0x88 0x91 0xe6 0x98 0xaf 0xe8 0xaa 0xb0
Size: 0 -