1

我正在制作一个程序,比如抽认卡,但基于控制台。在程序开始时,我从一个包含 UTF-8 编码的日文字符(例如"ひらがな, カタカナ, 患者")的文件中读取。但是,当我调用 时std::getline(),输入输出为"". 我怎样才能做到这一点?也许STD_INPUT_HANDLE作为文件打开?我使用SetConsoleOutputCP()and SetConsoleCP()withCP_UTF8作为参数来启用 UTF-8 打印。

问题在行动

@πάντα ῥεῖ要求的最小可重现示例

#include <iostream>
#include <Windows.h>
#include <fstream>
#include <vector>
#include <string>

void populate(std::vector<std::string>& in) {
    std::ifstream file("words.txt"); // fill this with some UTF-8 characters, then check the contents of [in]

    std::string line;
    while (std::getline(file, line)) {
        in.emplace_back(line);
    }
}

int main() {
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);

    SetConsoleTitleA("Example");

    std::vector<std::string> arr;
    populate(arr);

    std::string input_utf8; // type some UTF-8 characters when asked for input
    std::cin >> input_utf8;

    for (std::string s : arr)
        if (input_utf8 == s)
            std::cout << "It works! The input wasn't null!";
}
4

1 回答 1

0

这个程序对我有用。我需要代码页 932 (Shift-JIS) 才能正确显示。(我的 Windows 10 机器上没有启用日语,所以它不依赖于此。)如果我只是std::cinstd::wcin,我可以在调试器中看到我没有得到正确的输入。但如果我使用ReadConsoleW/WriteConsoleW一切看起来都是正确的。

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>

using namespace std;

int main()
{
                                        //This code-page-changing stuff, plus the restoring later, is from
                                        //https://www.codeproject.com/articles/34068/unicode-output-to-the-windows-console
    UINT oldcp = GetConsoleOutputCP();  //what is the current code page? store for later
    SetConsoleOutputCP(932);            //set it up so it can do Japanese

    cout << "Enter something: "; 

    wchar_t wmsg[32];
    DWORD used;
    if (!ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
        wmsg,
        31, //because wmsg has 32 slots. ?
        &used,
        nullptr))
        cerr << "ReadConsole failed, le = " << GetLastError() << endl;

    size_t len = used;
    cout << "You entered: ";
    //From https://cboard.cprogramming.com/windows-programming/112382-printing-unicode-console.html
    if (!WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), 
            wmsg, (DWORD) len,
            &used, 0))
            cerr << "WriteConsole failed, le = " << GetLastError() << endl;
    cout << '\n';

    cout << "Hit enter to end (and restore previous code page)."; cin.get();
    SetConsoleOutputCP(oldcp); SetConsoleCP(oldcp);
    return 0;
}
于 2021-11-10T20:52:09.877 回答