从焦炭创建UTF-16串*(Create UTF-16 string from char*)

2019-08-17 16:06发布

所以,我有标准的C字符串:

char* name = "Jakub";

我想将其转换为UTF-16。 我想通了,那UTF-16将延长一倍 -一个字需要两个字符。
所以我创建另一个字符串:

char name_utf_16[10];  //"Jakub" is 5 characters

现在,我相信与ASCII字符我只会用低字节,所以对于所有的人就会像74 00J等。 抱着这个信念,我可以让这样的代码:

void charToUtf16(char* input, char* output, int length) {
    /*Todo: how to check if output is long enough?*/
    for(int i=0; i<length; i+=2)  //Step over 2 bytes
    {
        //Lets use little-endian - smallest bytes first
        output[i] = input[i];
        output[i+1] = 0;  //We will never have any data for this field
    }
}

但是,在这个过程中,我结束了"Jkb" 。 我知道没有办法正确测试这一点 - 我刚刚发送的字符串的Minecraft Bukkit服务器。 而这也正是它在断开说:

十三点34分19秒[INFO]断开JKB ?? [/127.0.0.1:53215]:过期的服务器!

注:我知道,我的世界使用大端。 上面的代码只是一个例子,其实,我有我的转换在课堂上实施。

Answer 1:

output[i] = input[i];

这将输入的每一个字节的其他分配,因为你增加i的2。所以难怪你获得"Jkb" 。 你可能想写:

output[i] = input[i / 2];


Answer 2:

为什么你想使自己的Unicode转换功能,即使世界上现有的C / C ++这个功能,如mbstowcs()它包含在<cstdlib>

如果你仍然想使你自己的东西,然后看看Unicode协会的开源代码,可以在这里找到:

转换UTF-16 UTF-8在Windows和Linux下,在C



Answer 3:

在我回答你的问题,可以这样考虑:

编程的这个区域充满了男人的陷阱。 这使得有很大的意义去理解,UTF7 / 8和ANSI /“多字节字符串(MBCS)” ASCII之间的差别,所有这些对说英语的程序员的外观和感觉是相同的,但需要的,如果他们是非常不同的处理引入到欧洲或亚洲用户。

ASCII:字符是范围32到127。 只有永远一个字节。 线索是在名字,他们都是伟大的美国人,但在世界其他地方不适合的目的。

ANSI / MBCS:这是“代码页”的原因。 人物32到127是相同的ASCII文件,但也可能有字符在128-255的范围内,以及额外的字符,一些128-255范围内的可作为一个标志标记字符继续到第二,第三或甚至第四字节。 要正确处理字符串,你需要两个字节的字符串和正确的代码页。 如果您尝试使用处理错误的代码页中的字符串,你不会有合适的角色,并曲解一个字符是否是一个,两个甚至4字节的字符。

UTF7 / 8:这些是21比特的Unicode字符点8位宽的格式。 在UTF-7和UTF-8 Unicode字符可以是一至四个字节长。 即UTF编码有超过ANSI优点/ MBCS的是,没有造成代码页歧义。 在每个脚本中的每个字形都有一个唯一的Unicode代码点,这意味着它是不可能通过解释不同的电脑与不同的区域设置上的数据裂伤的字符集。

因此,要开始回答你的问题:

  1. 虽然你正在假定你的char *只会点为ASCII字符串,这是一个非常危险的抉择,用户在键入的,不是程序员的数据的控制。 Windows程序将保存这个作为默认MBCS。

  2. 正在制作的第二个假设是一个UTF-16编码将是一个8位编码的大小的两倍。 这不是通常一个安全的假设。 取决于编码UTF-16编码可以是两倍大小的来源,可以是小于两倍的尺寸,并且在一个极端的例子实际上可以是在长度短。

那么,什么是安全的解决方案?

安全的选择是在内部实现应用程序为Unicode。 在Windows中,这是一个编译器选项,然后意味着你的窗口控制所有使用的wchar_t *字符串的数据类型。 在Linux上我不太确定,你可以随时使用unicide显卡和操作系统库。 你也必须使用wcslen()函数来获取字符串的长度等等。当你与外部世界的互动,在使用的字符编码精确。

要回答你的问题就成为改变到,我该怎么办的问题,当我接收非UTF-16数据?

首先,是关于你在做它的格式是什么的假设很清楚了吗? 其次,接受这样的事实,有时转换为UTF-16可能会失败。

如果你是清楚的源格式,你可以再选择适当的Win32或STL转换器转换格式,然后你应该寻找证据使用结果之前转换失败。 例如mbstowcs或的MultiByteToWideChar()的窗口上。 然而,使用这两种方法的安全意味着你需要了解以上所有的答案。

所有其他选项引入风险。 使用MBCS字符串,你将不得不使用一个代码页被输入损坏的数据串,并使用不同的代码页处理。 假设ASCII数据,当你遇到一个非ASCII字符代码将打破,会让你“怪”的用户对你的短缺憾。



文章来源: Create UTF-16 string from char*