为什么mingw-w64上的`std :: mbrlen`总是返回一个(`1`)

时间:2018-05-30 10:53:33

标签: c++ mingw-w64 multibyte-functions

当我在mingw-w64中编译以下源代码时,我总是从std::mbrlen得到1(一)个字节:

#include <cstddef>
#include <cstdio>
#include <clocale>
#include <cstring>
#include <cwchar>

void print_mb(const char* ptr)
{
  std::size_t index{0};
  const char* end = ptr + std::strlen(ptr);
  int len;
  while((len = std::mbrlen(ptr, end-ptr, nullptr)) > 0)
  {
    std::printf("Character #%zu is %i bytes long.\n", index++, len);
    ptr += len;
  }
}

int main()
{
  std::setlocale(LC_ALL, "en_US.utf8");
  const char* str = "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9d\x84\x8b";
  print_mb(str);
}

示例代码基于std::mbrtowc页面

中的代码

我在mingw-w64下用

编译了这个样本
gcc sample.cxx

我从程序中得到以下输出:

Character #0 is 1 bytes long.
Character #1 is 1 bytes long.
Character #2 is 1 bytes long.
Character #3 is 1 bytes long.
Character #4 is 1 bytes long.
Character #5 is 1 bytes long.
Character #6 is 1 bytes long.
Character #7 is 1 bytes long.
Character #8 is 1 bytes long.
Character #9 is 1 bytes long.

但如果我使用&#34; online&#34;编译相同的代码cppreference page上的编译器,例如与Arch Linux下的GCC(再次使用简单gcc sample.cxx),与Microsoft Visual C ++ 2017(使用英特尔C ++编译器2018(cl sample.cxx)的icl sample.cxx),,我明白这一点:

Character #0 is 1 bytes long.
Character #1 is 2 bytes long.
Character #2 is 3 bytes long.
Character #3 is 4 bytes long.

在mingw-w64下可能导致std::mbrlen的这种行为?感谢。

我的Microsoft Windows主机是Microsoft Windows 10 x86-64。在此主机上进行的mingw-w64,Microsoft Visual C ++和Intel C ++下的编译。

1 个答案:

答案 0 :(得分:0)

Windows不支持通过C和C ++语言环境添加utf8。

https://msdn.microsoft.com/en-us/library/x99tb11d.aspx

  

可用区域设置名称,语言,国家/地区代码和代码页的集合包括Windows NLS API支持的所有内容,除了每个字符需要两个以上字节的代码页,例如UTF-7和UTF-8

此外,Windows上的区域设置名称与Linux上的区域设置名称不同,例如setlocale( LC_ALL, "English_United States.1252" );

C和C ++语言环境系统是实现定义的,唯一可用的实现是Linux(glibc)中的实现。

在Windows上,如果您需要UTF-8或其他Unicode内容,则需要使用Windows API或其他库。