c++ - 将字符串转换为UTF8字符串所需

标签 c++ c utf-8 iconv wchar-t

问题陈述:
我需要将生成的字符串转换为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);
}


这里有一个问题:

输出是


  Prova ?????
  
  s



为什么这里没有打印尺寸?
为什么第二个printf只打印一个字符。
如果我在两个已打印的字符串之前都打印了大小,则仅打印5个字符串,并且两个字符串都从控制台丢失。



转到第二部分:

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

为此,我浏览了一下,发现iconv在这里会有所帮助。

在这里提问
这些是我在manual中找到的方法

**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

最佳答案

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


'?????'在哪里来自?在调用mbstowcs(WcharString, CharString, strlen(CharString))中,最后一个参数(strlen(CharString))是输出缓冲区的长度,而不是输入字符串的长度。 mbstowcs所写的宽字符(包括NUL终止符)不得超过该数量。由于转换需要包括终止符在内的6个宽字符,并且您只允许它写入5个宽字符,因此生成的宽字符串不会以NUL终止,并且当您尝试将其打印出来时,最终会在结束后打印垃圾转换后的字符串。因此,?????。您应该使用wchar_t的输出缓冲区的大小(在本例中为255)。
为什么第二个wprintf只打印一个字符?当使用宽字符串参数调用wprintf时,必须使用%ls格式代码(或更准确地说,%s转换需要使用l长度修饰符进行限定)。如果在不使用%s的情况下使用l,则wprintf会将字符串解释为char*,并在将其输出时将每个字符转换为wchar_t。但是,由于参数实际上是一个宽字符串,因此字符串中的第一个wchar_tL"p",它是某个整数大小的数字0x70。这意味着wchar_t的第二个字节(从末尾开始计数,因为您使用的是Little-endian体系结构)为0,因此,如果将字符串视为字符串,则它将在< cc>。因此只打印一个字符。
为什么最后一个p不打印任何内容?在C语言中,输出流可以是宽流也可以是字节流,但是在打开流时无需指定。 (并且,无论如何,标准输出已经为您打开。)这称为流的方向。新打开的流是未定向的,并且在首次输出到该流时该定向是固定的。如果第一个输出调用是广泛调用,例如printf,则该流是广泛流;否则,它是一个字节流。设置后,方向是固定的,您不能使用方向错误的输出调用。因此,wprintf是非法的,除了引发错误外,它什么也不做。




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

首先,您需要清楚输入的格式以及输出方式。在Linux上,根本不可能使用printf。输入字符串最可能的情况是它已经是UTF-8,或者已经以某些ISO-8859-x编码。输出的最可能情况是相同的:要么是UTF-8,要么是某种ISO-8859-x编码。

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

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

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

您当然可以使用mbstowcs将字符串从一种编码转换为另一种编码。您无需执行iconv即可。但是您确实需要知道实际的输入编码和所需的输出编码。

关于c++ - 将字符串转换为UTF8字符串所需,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30918551/

相关文章:

c++ - 如何使用 QT WebEngine 发送 HTTPHeader?

C - 查找句子中最长的单词

c++ - 在迭代时修改数据结构

c++ - 在 libcurl ssl 请求中发送客户端证书时遇到问题,我缺少什么?

c - 不断得到预期 'const char *'

Php 阿拉伯字符没有正确连接

php - 比较 PHP 的 NumberFormatter::formatCurrency 结果

java - 使用 base64 对字符串值进行编码

c# - c++代码(malloc方法)到c#代码

清除部分虚拟内存?