Почему `std :: mbrlen` на mingw-w64 всегда возвращает единицу (` 1`) - PullRequest
0 голосов
/ 30 мая 2018

Когда я компилирую следующий исходный код в mingw-w64, я всегда получаю 1 (один) байт из 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 , например, или с GCC под ArchLinux (опять с простыми 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 ++ производится на этом хосте.

1 Ответ

0 голосов
/ 30 мая 2018

Windows не поддерживает utf8 через локали C и C ++.

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 или другим библиотекам.

...