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

C++ 需要将字符串转换为UTF8字符串,c++,c,utf-8,iconv,wchar-t,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"; ic

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

输出为

普罗瓦

为什么不在这里打印尺寸? 为什么第二个printf只打印一个字符。 如果我在两个打印字符串之前打印大小,则只打印5,并且控制台中缺少两个字符串。 继续第二部分:

现在我有了一个wchar\u t字符串,我想把它转换成UTF8字符串

为此,我浏览了一下,发现iconv将在这里提供帮助

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

在馈送到iconv之前,是否需要将wchar\u t数组转换回char数组

请就上述问题提出建议

我所说的扩展ascii请参见下面标记的快照中的字母I
将iconv用于utf8不是一个好主意。只需自己实现utf8的定义。从描述来看,这在C语言中很容易实现。 您甚至不需要wchar,只需为您的角色使用uint32即可。
如果您自己实现,您将学到很多,并且您的程序将从不使用mb或iconv函数中获得速度。

对于您的第一个问题,我解释为为什么所有输出都不是我期望的:

这个“??”来自哪里?在调用mbstowcsWcharString、CharString、strlenCharString时,最后一个参数strlenCharString是输出缓冲区的长度,而不是输入字符串的长度。mbstowcs不会写入超过该数量的宽字符,包括NUL终止符。由于转换需要包括终止符在内的6个宽字符,并且您只允许它写入5个宽字符,因此生成的宽字符串不是NUL终止的,当您尝试打印它时,您最终会在转换字符串结束后打印垃圾。因此""?????。在本例中,您应该使用wchar\u t的255中输出缓冲区的大小

为什么第二个wprintf只打印一个字符?使用宽字符串参数调用wprintf时,必须使用%ls格式代码,或者更准确地说,需要使用l长度修饰符限定%s转换。如果使用不带l的%s,则wprintf会将字符串解释为char*,并在输出时将每个字符转换为wchar\u t。但是,由于参数实际上是一个宽字符串,因此字符串中的第一个wchar\u t是Lp,它是某个整数大小的数字0x70。这意味着wchar_t的第二个字节从末尾开始计数,因为您有一个小小的endian体系结构,所以如果您将该字符串视为一个字符串,它将在p之后立即终止。因此,只打印一个字符

为什么最后一个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就可以做到这一点。但是您确实需要知道实际的输入编码和所需的输出编码。

不是wprintfLs\n,WcharString;应为wprintfL%s\n,字符串;或者什么?部分相关:在Linux上几乎没有人使用wchar\u t,但所有字符串通常都是用UTF-8编码的窄字符串char*;您是否明确选择使用wchar\t?如果是,为什么?或者它是由您正在使用的某个库强制执行的?您所说的作为输入的扩展ASCII是什么意思?它是一个字节数组,其中每个字节对应一个字符,即使是128或更高的值?那你为什么要使用wchar\t呢?一个简单的表格,带有256个条目对应的UTF-8字节序列,您就完成了。@SouravGhosh是的,错过了它。我应该在这里放屏幕截图,这里没有扩展ascii。要输出字符串,OP仍然需要wchar\u t where–嘿!同样,这很重要,但在帖子中没有提到我猜他在窗户上。但我同意UTF8的实现非常简单。大多数人认为UTF8是一种魔力,但它只是一种简单的编码,只剩下7位ascii码,而编码其余的24位unicode值。如果输出确实需要wchar\t,则取决于要编码的编码。但如果你问我,我会干脆扔掉任何仍然使用传统字符表的系统。对于gcc,我认为wchar_t在x86_84上定义为int,非常感谢。这正是我所期待的,一个能深入详细地告诉我的人,你最后的建议似乎很好。我会这样做,并张贴在这里,无论发生什么。是的,你答对了,我正在通过油灰连接:再次感谢你。
**iconv_t iconv_open(const char *, const char *);

size_t  iconv(iconv_t, char **, size_t *, char **, size_t *);

int     iconv_close(iconv_t);**