我怎样才能 cin 和 cout 一些 unicode 文本?
我问一个代码片段,它输入一个 unicode 文本,将另一个 unicode 连接到第一个 unicode 文本,然后输出结果.
I ask a code snippet which cin a unicode text, concatenates another unicode one to the first unicode text and the cout the result.
附:这段代码将帮助我解决另一个更大的 unicode 问题.但在关键是完成我的要求之前.
P.S. This code will help me to solve another bigger problem with unicode. But before the key thing is to accomplish what I ask.
添加:顺便说一句,当我运行可执行文件时,我无法在命令行中写入任何 unicode 符号.我应该怎么做?
ADDED: BTW I can't write in the command line any unicode symbol when I run the executable file. How I should do that?
推荐答案
这里有一个例子,展示了四种不同的方法,其中只有第三种(C conio
)和第四种(原生 Windows API) 工作(但前提是标准输入/标准输出没有被重定向).请注意,您仍然需要包含要显示的字符的字体(Lucida Console 至少支持希腊语和西里尔语).请注意,这里的所有内容都是完全不可移植的,只是没有可移植的方式在终端上输入/输出 Unicode 字符串.
Here is an example that shows four different methods, of which only the third (C conio
) and the fourth (native Windows API) work (but only if stdin/stdout aren't redirected). Note that you still need a font that contains the character you want to show (Lucida Console supports at least Greek and Cyrillic). Note that everything here is completely non-portable, there is just no portable way to input/output Unicode strings on the terminal.
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#define STRICT
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <conio.h>
#include <windows.h>
void testIostream();
void testStdio();
void testConio();
void testWindows();
int wmain() {
testIostream();
testStdio();
testConio();
testWindows();
std::system("pause");
}
void testIostream() {
std::wstring first, second;
std::getline(std::wcin, first);
if (!std::wcin.good()) return;
std::getline(std::wcin, second);
if (!std::wcin.good()) return;
std::wcout << first << second << std::endl;
}
void testStdio() {
wchar_t buffer[0x1000];
if (!_getws_s(buffer)) return;
const std::wstring first = buffer;
if (!_getws_s(buffer)) return;
const std::wstring second = buffer;
const std::wstring result = first + second;
_putws(result.c_str());
}
void testConio() {
wchar_t buffer[0x1000];
std::size_t numRead = 0;
if (_cgetws_s(buffer, &numRead)) return;
const std::wstring first(buffer, numRead);
if (_cgetws_s(buffer, &numRead)) return;
const std::wstring second(buffer, numRead);
const std::wstring result = first + second + L'
';
_cputws(result.c_str());
}
void testWindows() {
const HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
WCHAR buffer[0x1000];
DWORD numRead = 0;
if (!ReadConsoleW(stdIn, buffer, sizeof buffer, &numRead, NULL)) return;
const std::wstring first(buffer, numRead - 2);
if (!ReadConsoleW(stdIn, buffer, sizeof buffer, &numRead, NULL)) return;
const std::wstring second(buffer, numRead);
const std::wstring result = first + second;
const HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD numWritten = 0;
WriteConsoleW(stdOut, result.c_str(), result.size(), &numWritten, NULL);
}
- 编辑1:我添加了一个基于
conio
的方法. - 编辑 2:我在 Michael Kaplan 的博客中描述了一点
_O_U16TEXT
,但似乎只有wgets
解释ReadFile
中的(8 位)数据为 UTF-16.我会在周末对此进行进一步调查. - Edit 1: I've added a method based on
conio
. - Edit 2: I've messed around with
_O_U16TEXT
a bit as described in Michael Kaplan's blog, but that seemingly only hadwgets
interpret the (8-bit) data fromReadFile
as UTF-16. I'll investigate this a bit further during the weekend.
相关文章