Всем спасибо за комментарии ! Решение найдено. Работает на 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
Вот оно что, вчера использовал и _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 для компиляции
Всё перетестил, оно вроде по идее работает, но походу до 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
Хотелось бы, чтобы было какое-нибудь решение до 15 строк, который можно было бы вставить в маленькую программку, чтоб там всё работало в UTF-8, и этот код компилировался бы всеми компиляторами
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
Потому ещё что Unix, Linux, MacOs и другие нормальные системы следуют стандартам Posix. А MS типа сами себе стандарт... Спасибо Cygwin что они следуют стандарту. ru.m.wikipedia.org/wiki/POSIX
@@talipovsn потому что они всегда всеми силами сохраняют обратную совместимость, а во времена MS-DOS никакого POSIX как стандарта еще и в помине не было.
Согласен. Но сделали бы опцию совместимости в компиляторе, могут же. Думаю это больше политика, чем технические проблемы.. Как и в C# для Linux в плане GUI
@@talipovsn начиная с Windows 10 появилась функция которая как раз позволяет приложениям из коробки поддерживать UTF-8, там и аргументы команды будут в этой кодировке влетать, и все системные функции тоже будут использовать UTF-8 вместо OEM кодировки.
Всем спасибо за комментарии ! Решение найдено. Работает на 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
Вот оно что, вчера использовал и _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 для компиляции
Всё перетестил, оно вроде по идее работает, но походу до 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
Хотелось бы, чтобы было какое-нибудь решение до 15 строк, который можно было бы вставить в маленькую программку, чтоб там всё работало в UTF-8, и этот код компилировался бы всеми компиляторами
оно найдено, смотрите закрепленный комментарий!
Спасибо. Очень интересно.
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
Потому ещё что Unix, Linux, MacOs и другие нормальные системы следуют стандартам Posix. А MS типа сами себе стандарт... Спасибо Cygwin что они следуют стандарту. ru.m.wikipedia.org/wiki/POSIX
@@talipovsn потому что они всегда всеми силами сохраняют обратную совместимость, а во времена MS-DOS никакого POSIX как стандарта еще и в помине не было.
Согласен. Но сделали бы опцию совместимости в компиляторе, могут же. Думаю это больше политика, чем технические проблемы.. Как и в C# для Linux в плане GUI
@@talipovsn начиная с Windows 10 появилась функция которая как раз позволяет приложениям из коробки поддерживать UTF-8, там и аргументы команды будут в этой кодировке влетать, и все системные функции тоже будут использовать UTF-8 вместо OEM кодировки.