Задать вопрос
  • Как считать из stdin русский текст и вывести его как wchar_t?

    Grinlex
    @Grinlex
    res2001, ну, тут да, корректное решение зависит от контекста конкретной программы

    Хотя вообще сейчас лучше вообще использовать std::print() или fmt::print(), тк они гарантированно обязаны вывести корректно utf-8 текст, если кодировка строкового литерала такая же ([ostream.formatted.print]).

    fmt это реализует через преобразование utf-8 в utf-16 и вызов функции WriteConsoleW

    f99c6cf6052691ffcbb63402fe9b000b.png

    ввода кстати не придумали ни в fmt, ни в стандарте, поэтому тут наверное можно использовать ReadConsoleW:
    код


    std::wstring ReadLineFromConsole() {
        HANDLE hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
        if (hConsoleInput == INVALID_HANDLE_VALUE) {
            return L"";
        }
    
        std::wstring result;
        const DWORD CHUNK_SIZE = 16; // можно сделать побольше
        wchar_t chunk[CHUNK_SIZE];
        DWORD charsRead = 0;
    
        while (true) {
            BOOL success = ReadConsoleW(hConsoleInput, chunk, CHUNK_SIZE, &charsRead, nullptr);
    
            if (!success || charsRead == 0) {
                break;
            }
    
            result.append(chunk, charsRead);
    
            if (result.back() == L'\n' || result.back() == L'\r') {
                break;
            }
        }
    
        while (!result.empty() && (result.back() == L'\n' || result.back() == L'\r')) {
            result.pop_back();
        }
    
        return result;
    }



    но это если совсем уже заморачиваться и совсем не хочется менять окружение. Для ввода чисел думаю и обычного cin достаточно.
    Написано
  • Как считать из stdin русский текст и вывести его как wchar_t?

    Grinlex
    @Grinlex
    Вряд ли пользователь не хочет, чтобы за него меняли кодировку консоли. Всё таки главное результат - читаемый текст.

    Не понимаю чем обыкновенный cin не устроил автора, раз он всё равно в C++. Этот код корректно работает сегодня на всех двух терминалах винды:
    #include <iostream>
    #include <windows.h>
    
    int main() {
        SetConsoleCP(CP_UTF8);
        SetConsoleOutputCP(CP_UTF8);
        const int BUFFER_SIZE = 12;
        char buffer[BUFFER_SIZE];
        std::cout << "Введите текст: ";
        std::cin.getline(buffer, BUFFER_SIZE);
        std::cout << "Вы ввели: " << buffer << std::endl;
        return 0;
    }


    51dead0b0a23172f052d59045c95ffdc.png

    Единственная проблема это то, что кодировка консоли не восстанавливается при выходе из программы. Можно конечно в начале программы вручную получать кодировку и в конце ее восстанавливать, но при сигналах, которые насильно закрывают процесс, её уже никак самому не восстановить. Тут единственный вариант я вижу чисто логировать все изменения среды, чтобы пользователь знал, как было до и что она поменяла
    Написано