Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mbrtowc返回-1表示嵌入式设备上的非ASCII字符,但在linux计算机上不返回_C_Linux_Character Encoding_Embedded_Buildroot - Fatal编程技术网

mbrtowc返回-1表示嵌入式设备上的非ASCII字符,但在linux计算机上不返回

mbrtowc返回-1表示嵌入式设备上的非ASCII字符,但在linux计算机上不返回,c,linux,character-encoding,embedded,buildroot,C,Linux,Character Encoding,Embedded,Buildroot,任务 目前,我正在用纯C语言将设备的旧DOS代码移植到Linux上。文本是在bitfonts的帮助下绘制在表面上的。我编写了一个函数,需要传递Unicode代码点,然后绘制相应的测试标志符号,并使用不同的ASCII和非ASCII字符。旧的源代码使用DOS编码,但我尝试使用UTF-8,因为需要多语言支持。我无法使用SDL_ttf或类似函数,因为生成的图示符不够精确。因此,我必须坚持使用bitfonts 发行 我写了一个小的C测试程序来测试多字节字符到它们对应的Unicode码点的转换,灵感来自于

任务

目前,我正在用纯C语言将设备的旧DOS代码移植到Linux上。文本是在bitfonts的帮助下绘制在表面上的。我编写了一个函数,需要传递Unicode代码点,然后绘制相应的测试标志符号,并使用不同的ASCII和非ASCII字符。旧的源代码使用DOS编码,但我尝试使用UTF-8,因为需要多语言支持。我无法使用SDL_ttf或类似函数,因为生成的图示符不够精确。因此,我必须坚持使用bitfonts

发行

我写了一个小的C测试程序来测试多字节字符到它们对应的Unicode码点的转换,灵感来自于

产出如预期:

处理7个UTF-8代码单元:[0x21 0xc2 0xb0 0xe6 0xb0 0xb4 0] 分为4个wchar_t单位:[33176 27700 0]

当我在嵌入式Linux设备上运行此代码时,我得到以下输出:

处理7个UTF-8代码单元:[0x21 0xc2 0xb0 0xe6 0xb0 0xb4 0] 分为2个wchar__t单位:[33 55264] 之后!mbrtowc输出的字符是-1,根据文档,它发生在编码错误时。我用不同的符号测试了它,这个错误只发生在非ASCII字符上。Linux计算机上从未发生错误

补充资料


我使用的是PFM-540I版本。B作为嵌入式设备上的pc。Linux发行版是使用Buildroot构建的。

您需要确保嵌入式Linux构建中的en_US.utf8区域设置可用。默认情况下,Buildroot以两种方式限制系统上安装的区域设置:

按照BR2_GENERATE_LOCALE configure选项的指定,只生成特定的区域设置。默认情况下,此列表为空,因此您只能获得C语言环境。将此配置选项设置为en_US.UTF-8。 生成结束时,将删除所有区域设置数据,但BR2_ENABLE_locale_白名单中指定的数据除外。en_US已经是默认值,所以您可能不需要更改它。
请注意,如果更改这些配置选项,则需要使用makeclean创建一个完全干净的构建;使更改生效。

Hmmm,嵌入式Linux设备第二次输出为十六进制,但预期输出为十进制。建议两者都使用十六进制%x,以提高后期清晰度。还建议在每次迭代的过程中检查rc。。。看看它是否是一个意外的值。我的错是,我尝试了不同的输出,但没有注意我发布的内容。已更正输出,因此现在显示十进制值。在第一个rc=1时,但在处理第一个字符且下一个字符为°后,它将变为rc=-1。这将停止while循环,因为发生了编码错误。希望这能澄清一些事情,比如设置localelc_CTYPE,en_US.utf8;在嵌入式Linux设备上成功吗?返回字符串或null指针?是,输出为null。如果嵌入式Linux设备返回null,则不需要en_US.utf8支持。mbrtowc应该返回-1.0,工作正常,但必须生成en_US.UTF-8 locale而不是en_US.utf8。未找到生成时,en_US.utf8区域设置导致错误。谢谢。好的,编辑好了。生成en_US.UTF-8时,en_US.utf8区域设置也可用,对吗?是的,刚刚验证过。两个地区都可用。
#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <wchar.h>
#include <stdint.h>

int main(void)
{
   size_t n = 0, x = 0;
   setlocale(LC_CTYPE, "en_US.utf8");
   mbstate_t state = {0};
   char in[] = "!°水"; // or u8"zß水"
   size_t in_sz = sizeof(in) / sizeof (*in);

   printf("Processing %zu UTF-8 code units: [ ", in_sz);
   for(n = 0; n < in_sz; ++n)
   {
      printf("%#x ", (unsigned char)in[n]);
   }
   puts("]");

   wchar_t out[in_sz];
   char* p_in = in, *end = in + in_sz;
   wchar_t *p_out = out;
   int rc = 0;
   while((rc = mbrtowc(p_out, p_in, end - p_in, &state)) > 0)
   {
       p_in += rc;
       p_out += 1;
   }

   size_t out_sz = p_out - out + 1;
   printf("into %zu wchar_t units: [ ", out_sz);
   for(x = 0; x < out_sz; ++x)
   {
      printf("%u ", (unsigned short)out[x]);
   }
   puts("]");
}