Виновник проблем с кодировкой UTF-8 и русскими буквами под Windows найден!

Поделиться
HTML-код
  • Опубликовано: 1 фев 2025

Комментарии • 21

  • @talipovsn
    @talipovsn  Год назад +2

    Всем спасибо за комментарии ! Решение найдено. Работает на Linux и Windows без сторонних библиотек и лишнего кода.
    Файл нужно сохранить в кодировке UTF-8 с cигнатурой BOM ! :
    #include
    #include
    #ifdef _WIN32 // Если это Windows
    #include
    #include
    #endif
    int main(int argc, char** argv)
    {
    setlocale(LC_ALL, "ru_RU.UTF-8"); // Установить русскую локаль для Linux
    #ifdef _WIN32
    _setmode(_fileno(stdout), _O_U16TEXT); // Установить Юникод для вывода в консоли Windows
    _setmode(_fileno(stdin), _O_U16TEXT); // Установить Юникод для ввода в консоли Windows
    _setmode(_fileno(stderr), _O_U16TEXT); // Установить Юникод для вывода ошибок в консоли Windows
    #endif
    std::wcout input; // Считать строку
    std::wcout

    • @sleepyNovember_project
      @sleepyNovember_project Год назад +1

      Вот оно что, вчера использовал и _setmode для stdin/stdout,
      и wcout/wcin, и wstring
      И даже макрос TEXT("слово"), который зависит от параметра в настройках проекта:
      >Свойства конфигурации
      Общие или дополнительные (не помню)
      Набор символов
      Если в параметрах проекта выбран unicode, TEXT подставляет кавычкам буковку L"..." , Если нет, ничего не делает.
      Но я всё неправильно понял, вот что усмотрел с разных источников, собрал в заметки:
      Макросы препроцессора:
      TCHAR = char / wchar_t
      WCHAR = wchar_t
      LPSTR = char*
      LPCSTR = const char*
      LPCWSTR = const wchar_t*
      LPCTSTR = const char* / const wchar_t*
      Имеющие букву T, зависят от уже вышеупомянутого параметра проекта. Включён unicode, TCHAR будет wchar_t, если же выбрана стандартная однобайтовая кодировка, он будет char-ом обычным.
      TEXT == "somestring" / L"somestring" || 'c' / L'c'
      Тот же гусь.
      Типы char и другие их префиксы:
      char == ASCII == 'c'
      wchar_t == UTF-16LE == L'w'
      char8_t == UTF-8 == u8'c' // "C++20"!!!
      char16_t == UTF-16 == u'w'
      char32_t == UTF-32 == U'w'
      char == до 0xFF (255)
      char8_t == до 0xFF (255)
      char_16t == до 0xFFFF (65536) //как и "wchar_t tchar = L'8';"
      char_32t == до 0xFFFFFFFF (4294967295) //O_O
      Строки char и char8_t типов, называются узкими строками,
      даже если используются для кодирования символов Юникода
      или нескольких байтов.
      Типы строк:
      string == char == ASCII "string"
      wstring == wchar_t == UTF-16LE L"string"
      u8string == char8_t == UTF-8 u8"string" // C++20
      u16string == char16_t == UTF-16 u"string
      u32string == char32_t == UTF-32 U"string"
      Надо будет ассумировать инфу, и посидеть потыкать визуал студию.
      А к кодировке UTF-8 я, чёрт возьми, почти и не пробовал закидывать BOOM*!
      P.S.
      Можно использовать в своих проектах собственные дефайны, которые будут зависеть от параметра проекта "Набор символов", к примеру
      #ifdef _UNICODE
      #define TSTRING std::wstring
      #define tcin std::wcin
      #define tcout std::wcout
      #else
      #define TSTRING std::string
      #define tcin std::cin
      #define tcout std::cout
      тогда похоже можно будет в настройках проекта правильно переключаться между ASCII/Unicode для компиляции

    • @sleepyNovember_project
      @sleepyNovember_project Год назад

      Всё перетестил, оно вроде по идее работает, но походу до 65535 символа отображает из юникода. Видимо такое ограничение на винде?
      Читал где-то что на винде wchar_t равен фиксированно 2 байтм, а на Линукс он вроде как 4, либо переменный 2-4.
      Значит там этот способ рабочий.
      У меня в стандартной консоли вот из этого списка отображается до Арабского. От него и после просто квадратики со знаком вопроса, но не различные закорючки.
      Список:
      Hello, World! - English
      Привет, мир! - Russian
      Привіт, Світ! - Ukrainian
      Сәлем Әлем! - Kazakh
      Салом Ҷаҳон! - Tajik
      Բարեւ Աշխարհ! - Armenian
      Witaj, Świecie! - Polish
      ¡Hola, Mundo! - Spanish
      مرحبا ، العالم! - Arabic
      שלום, עולם! - Hebrew
      हैलो, दुनिया! - Hindi
      สวัสดีโลก! - Thai
      வணக்கம், உலகம்! - Tamil
      హలో, ప్రపంచ! - Telugu
      ہیلو ، دنیا! - Urdu
      你好, 世界! - Chinese
      こんにちは、世界! - Japanese
      안녕하세요,세계! - Korean
      🙋, 🌏 ❗ - Emoji
      Потом надо будет прознать инфу про char32_t и зачем он.
      P.S. Потыкал шрифты,
      на Courier New проглядываются плюсом "Arabic, Hebrew Urdu"
      На Ms Gothic и NSimSun - "Chinese, Japanese, Korean"
      На SimSun-ExtB самый широкий диапазон:
      Все до Hebrew (включая), Thai, Urdu, Chinese, Japanese и Korean
      Что вообще тут происходит.
      Предполагаю, возможно это из-за разного расположения кодов символов в самих шрифтах.
      P.S.S действительно, на MSDN
      Поддерживаемые кодовые страницы фонтом Consola:
      1252 Latin 1
      1250 Latin 2: Eastern Europe
      1251 Cyrillic
      1253 Greek
      1254 Turkish
      1257 Windows Baltic
      1258 Vietnamese
      Mac Roman Macintosh Character Set (US Roman)
      OEM OEM Character Set
      869 IBM Greek
      866 MS-DOS Russian
      865 MS-DOS Nordic
      863 MS-DOS Canadian French
      861 MS-DOS Icelandic
      860 MS-DOS Portuguese
      857 IBM Turkish
      855 IBM Cyrillic; primarily Russian
      852 Latin 2
      775 MS-DOS Baltic
      737 Greek; former 437 G
      850 WE/Latin 1
      437 US

  • @minkinayu
    @minkinayu Год назад +1

    Хотелось бы, чтобы было какое-нибудь решение до 15 строк, который можно было бы вставить в маленькую программку, чтоб там всё работало в UTF-8, и этот код компилировался бы всеми компиляторами

    • @talipovsn
      @talipovsn  Год назад +1

      оно найдено, смотрите закрепленный комментарий!

  • @ataki2023
    @ataki2023 Год назад +2

    Спасибо. Очень интересно.

  • @IExSet
    @IExSet Год назад +2

    Unix operating system family use UTF-8 encoding by default.
    Microsoft Windows had migrated to Wide/UTF-16 API. The narrow encodings had been deprecated and the native OS API became so called "Wide API"
    As a result of radically different approaches, it is very hard to write portable Unicode aware applications.
    Компилятор и библиотека Cygwin видимо как то имитируют UTF-8 под Windows

    • @talipovsn
      @talipovsn  Год назад +1

      Потому ещё что Unix, Linux, MacOs и другие нормальные системы следуют стандартам Posix. А MS типа сами себе стандарт... Спасибо Cygwin что они следуют стандарту. ru.m.wikipedia.org/wiki/POSIX

    • @cyrez2402
      @cyrez2402 Год назад +3

      ​@@talipovsn потому что они всегда всеми силами сохраняют обратную совместимость, а во времена MS-DOS никакого POSIX как стандарта еще и в помине не было.

    • @talipovsn
      @talipovsn  Год назад

      Согласен. Но сделали бы опцию совместимости в компиляторе, могут же. Думаю это больше политика, чем технические проблемы.. Как и в C# для Linux в плане GUI

    • @cyrez2402
      @cyrez2402 Год назад

      @@talipovsn начиная с Windows 10 появилась функция которая как раз позволяет приложениям из коробки поддерживать UTF-8, там и аргументы команды будут в этой кодировке влетать, и все системные функции тоже будут использовать UTF-8 вместо OEM кодировки.