mbtowc如何使用区域设置?

时间:2017-02-12 19:29:40

标签: c unicode windows-console string-conversion widechar

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

我在Windows上使用GCC 4.8.1(其中sizeof wchar_t为2),使用捷克语区域设置(cs_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();
}

以下是setlocale设置和a的结果:

setlocale(LC_CTYPE,"Czech_Czech Republic.1250"); // a = 139 wrong
setlocale(LC_CTYPE,"Czech_Czech Republic.852"); //  a = 253c wrong

为什么mbtowc没有给出0x159 - un的unicode数?

0 个答案:

没有答案