繁体   English   中英

需要将字符串转换为 UTF8 字符串

[英]Required to convert a String to UTF8 string

问题陈述:我需要将生成的字符串转换为UTF8字符串,这个生成的字符串扩展了ascii字符,我在Linux系统(2.6.32-358.el6.x86_64)上。

POC 仍在进行中,所以我只能提供小代码示例,完整的解决方案只能在准备好后发布。

为什么我需要 UFT8(我扩展了 ascii 字符以存储在必须是 UTF8 的字符串中)。

我是如何进行的:

  • 将生成的字符串转换为 wchar_t 字符串。

请看下面的示例代码

int main(){
  char  CharString[] = "Prova";
  iconv_t cd;
  wchar_t  WcharString[255];

  size_t size= mbstowcs(WcharString, CharString, strlen(CharString));

  wprintf(L"%ls\n", WcharString);

  wprintf(L"%s\n", WcharString);

  printf("\n%zu\n",size);
}

这里有一个问题:

输出是

普罗娃????

  1. 为什么这里没有打印尺寸?
  2. 为什么第二个 printf 只打印一个字符。
  3. 如果我在打印的两个字符串之前打印 size ,那么只打印 5 并且两个字符串都从控制台中丢失。


进入第二部分:

现在我将有一个 wchar_t 字符串,我想将其转换为 UTF8 字符串

为此,我正在浏览并发现 iconv 会在这里有所帮助。

问题在这里这些是我在 手册中找到的方法

**iconv_t iconv_open(const char *, const char *); size_t iconv(iconv_t, char **, size_t *, char **, size_t *); int iconv_close(iconv_t);**

在喂给 iconv 之前,我是否需要将 wchar_t 数组转换回 char 数组?

请就上述问题提出建议。

我正在谈论的扩展 ascii 请参见下面标记快照中的字母 i在此处输入图片说明

对于您的第一个问题(我将其解释为“为什么所有输出都不是我所期望的”):

  1. '?????' 在哪里? 来自? 在调用mbstowcs(WcharString, CharString, strlen(CharString)) ,最后一个参数 ( strlen(CharString) ) 是输出缓冲区的长度,而不是输入字符串的长度。 mbstowcs不会写入超过该数量的宽字符,包括 NUL 终止符 由于转换需要包括终止符在内的 6 个宽字符,并且您只允许它写入 5 个宽字符,因此生成的宽字符串不会以 NUL 终止,并且当您尝试将其打印出来时,您最终会在结束后打印垃圾转换后的字符串。 因此????? . 您应该使用wchar_t中的输出缓冲区的大小(在本例中为 255)。

  2. 为什么第二个wprintf只打印一个字符? 当您使用宽字符串参数调用wprintf时,您必须使用%ls格式代码(或者,更准确地说, %s转换需要用l长度修饰符限定)。 如果您使用%s而不使用l ,则wprintf会将字符串解释为char* ,并且在输出时会将每个字符转换为wchar_t 然而,由于参数实际上是一个宽字符串,字符串中的第一个wchar_tL"p" ,它是某个整数大小的数字0x70 这意味着,第二个字节wchar_t (从结尾开始计算,因为你有一个小端架构)是0,所以如果你把字符串作为字符的字符串,它会立即终止后p 所以只打印一个字符。

  3. 为什么最后一个printf打印任何东西? 在 C 中,输出流可以是宽流字节流,但您在打开流时没有指定。 (而且,无论如何,标准输出已经为您打开了。)这称为流的方向 新打开的流是无方向的,当您第一次输出到流时方向是固定的。 如果第一个输出调用是宽调用,如wprintf ,则流是宽流; 否则,它是一个字节流。 一旦设置,方向就固定了,您不能使用错误方向的输出调用。 所以printf是非法的,它除了引发错误之外什么也不做。


现在,让我们继续你的第二个问题:我该怎么办?

第一件事是你需要清楚输入的格式是什么,以及你想如何输出它。 在 Linux 上,您不太可能想要使用wchar_t 输入字符串最可能的情况是它已经是 UTF-8,或者它是某种 ISO-8859-x 编码。 输出的最可能情况是相同的:要么是 UTF-8,要么是某种 ISO-8859-x 编码。

不幸的是,您的程序无法知道控制台期望的是什么编码。 输出甚至可能不会进入控制台。 同样,您的程序确实无法知道输入字符串中使用的是哪种 ISO-8859-x 编码。 (如果它是字符串文字,则可能会在调用编译器时指定编码,但没有提供信息的标准方法。)

如果由于非 ascii 字符显示不正确而无法查看输出,则应首先确保将控制台配置为使用与程序输出相同的编码。 如果程序将 UTF-8 发送到显示 ISO-8859-15 的控制台,则文本将无法正确显示。 理论上,您的区域设置包括您的控制台使用的编码,但如果您使用的是远程控制台(例如,通过 Windows 机器上的 PuTTY),则控制台不是 Linux 环境的一部分,默认区域设置可能不正确. 最简单的解决方法是正确配置您的控制台,但也可以更改 Linux 区域设置。

您从字节字符串使用mbstowcs的事实表明您相信原始字符串是 UTF-8。 因此,问题似乎不太可能是您需要将其转换UTF-8。

您当然可以使用iconv将字符串从一种编码转换为另一种编码; 你不需要通过wchar_t来这样做。 但是您确实需要知道实际的输入编码和所需的输出编码。

对 utf8 使用 iconv 不是一个好主意。 自己实现utf8的定义就行了。 从描述https://en.wikipedia.org/wiki/UTF-8用 C 语言很容易做到这一点。 您甚至不需要 wchar_t,只需将 uint32_t 用于您的角色。 如果您自己实现,您将学到很多东西,并且您的程序将通过不使用 mb 或 iconv 函数来提高速度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM