为什么 mingw-w64 上的 `std::mbrlen` 总是 return 一个 (`1`)
Why does `std::mbrlen` on mingw-w64 always return one (`1`)
当我在 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.
但是如果我在 cppreference page 上使用 "online" 编译器编译相同的代码,例如 或 使用 Arch Linux 下的 GCC (再次使用简单的 gcc sample.cxx
), 或 使用 Microsoft Visual C++ 2017 (cl sample.cxx
),使用 或 使用 Intel C++ 编译器2018 (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.
什么可能导致 std::mbrlen
在 mingw-w64 下的这种行为?谢谢。
我的 Microsoft Windows 主机是 Microsoft Windows 10 x86-64。本机mingw-w64、Microsoft Visual C++ 和Intel C++ 下编译
Windows 不通过 C 和 C++ 语言环境支持 utf8。
https://msdn.microsoft.com/en-us/library/x99tb11d.aspx
The set of available locale names, languages, country/region codes, and code pages includes all those supported by the Windows NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8.
此外,Windows 上的语言环境名称与 Linux 上的不同,例如setlocale( LC_ALL, "English_United States.1252" );
C 和 C++ 语言环境系统是实现定义的,唯一可用的实现是 Linux (glibc) 中的实现。
在 Windows 上,如果您需要 UTF-8 或其他 Unicode 内容,您需要求助于 Windows API 或其他库。
当我在 mingw-w64 中编译以下源代码时,我总是从 std::mbrlen
:
#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.
但是如果我在 cppreference page 上使用 "online" 编译器编译相同的代码,例如 或 使用 Arch Linux 下的 GCC (再次使用简单的 gcc sample.cxx
), 或 使用 Microsoft Visual C++ 2017 (cl sample.cxx
),使用 或 使用 Intel C++ 编译器2018 (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.
什么可能导致 std::mbrlen
在 mingw-w64 下的这种行为?谢谢。
我的 Microsoft Windows 主机是 Microsoft Windows 10 x86-64。本机mingw-w64、Microsoft Visual C++ 和Intel C++ 下编译
Windows 不通过 C 和 C++ 语言环境支持 utf8。
https://msdn.microsoft.com/en-us/library/x99tb11d.aspx
The set of available locale names, languages, country/region codes, and code pages includes all those supported by the Windows NLS API except code pages that require more than two bytes per character, such as UTF-7 and UTF-8.
此外,Windows 上的语言环境名称与 Linux 上的不同,例如setlocale( LC_ALL, "English_United States.1252" );
C 和 C++ 语言环境系统是实现定义的,唯一可用的实现是 Linux (glibc) 中的实现。
在 Windows 上,如果您需要 UTF-8 或其他 Unicode 内容,您需要求助于 Windows API 或其他库。