Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.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
mbtowc如何使用语言环境?_C_Unicode_Windows Console_String Conversion_Widechar - Fatal编程技术网

mbtowc如何使用语言环境?

mbtowc如何使用语言环境?,c,unicode,windows-console,string-conversion,widechar,C,Unicode,Windows Console,String Conversion,Widechar,我很难使用mbtowc,它总是返回错误的结果。这也让我困惑,为什么函数甚至使用locale?多字节unicode字符点与语言环境无关。我实现了自定义转换函数,可以很好地进行转换,请参见下面的代码 我在Windows上使用GCC4.8.1(其中wchar\u t的大小为2),使用捷克语言环境(cs\u CZ)。OEM代码页是windows-1250,控制台默认使用CP852。以下是我目前的研究结果: #include <stdio.h> #include <stdlib.h>

我很难使用
mbtowc
,它总是返回错误的结果。这也让我困惑,为什么函数甚至使用locale?多字节unicode字符点与语言环境无关。我实现了自定义转换函数,可以很好地进行转换,请参见下面的代码

我在Windows上使用GCC4.8.1(其中wchar\u t的大小为2),使用捷克语言环境(cs\u CZ)。OEM代码页是windows-1250,控制台默认使用CP852。以下是我目前的研究结果:

#include <stdio.h>
#include <stdlib.h>

// my custom conversion function
int u8toint(const char* str) {
  if(!(*str&128)) return *str;
  unsigned char c = *str, bytes = 0;
  while((c<<=1)&128) ++bytes;
  int result = 0;
  for(int i=bytes; i>0; --i) result|= (*(str+i)&127)<<(6*(bytes-i));
  int mask = 1;
  for(int i=bytes; i<6; ++i) mask<<= 1, mask|= 1;
  result|= (*str&mask)<<(6*bytes);
  return result;
}

// data inspecting type for the tests in main()
union data {
  wchar_t w;
  struct {
    unsigned char b1, b2;
  } bytes;
} a,b,c;

int main() {
  // I tried setlocale here
  mbtowc(NULL, 0, 0); // reset internal mb_state
  mbtowc(&(a.w),"ř",6); // apply mbtowc
  b.w = u8toint("ř");   // apply custom function
  c.w = L'ř';           // compare to wchar

  printf("\na = %hhx%hhx", a.bytes.b2, a.bytes.b1); // a = 0c5 wrong
  printf("\nb = %hhx%hhx", b.bytes.b2, b.bytes.b1); // b = 159 right
  printf("\nc = %hhx%hhx", c.bytes.b2, c.bytes.b1); // c = 159 right
  getchar();
}

为什么
mbtowc
没有给出0x159——ř的unicode数字?

在源代码中放置非ASCII标志符号是有风险的,现在它关系到文本编辑器使用的编码方式以及编译器猜测的内容。看起来是utf8,将“ř”变成0xc5 0x99。这不是一个多字节代码。但是0xc5正确地在代码页1250中为Ĺ字形生成U+0139,在代码页852中为方框图形字形生成U+253C。不太清楚u8toint()的作用,但它似乎也假定为utf8。考虑将控制台切换到UTF8,同时停止出血。<代码> MbToWC.<代码>将从当前区域中编码的多字节字符转换为WCHARGET.ř是
“\xf8”
,CP852中的代码>是
“\xfd”
。尝试使用相应的编码将它们转换为广域,您将得到正确的答案。@HansPassant源代码为UTF-8。尽管chcp 65001将控制台切换到UTF-8输出,
。有趣的是,
mbstowcs
仅使用默认的“C”语言环境来转换字符串中的字节。@MarkTolonen回答得很好。解决方案可以是将源代码存储在与控制台区域设置相同的CP中,在Windows上不能是UTF-8。看起来
mbtowc
在使用UTF-8的Windows上注定要失败。Win32 API处理UTF-8。
setlocale(LC_CTYPE,"Czech_Czech Republic.1250"); // a = 139 wrong
setlocale(LC_CTYPE,"Czech_Czech Republic.852"); //  a = 253c wrong