我怎样才能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:我对
_O_U16TEXT
进行了一些处理,如 Michael Kaplan 的博客中所述,但似乎只有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.
相关文章