C++ 如何输入和输出一些unicode文本?

C++ 如何输入和输出一些unicode文本?,c++,windows,unicode,console,C++,Windows,Unicode,Console,我问了一个代码片段,其中包含一个unicode文本,将另一个unicode文本连接到第一个unicode文本,然后输出结果 另外,这段代码将帮助我解决unicode的另一个更大的问题。但在这之前,关键是完成我的要求 添加:顺便说一句,当我运行可执行文件时,我不能在命令行中写入任何unicode符号。我应该怎么做?这取决于操作系统。如果您的操作系统理解,您可以简单地将UTF-8序列发送给它。取决于您所指的unicode类型。我想你的意思是你只是在使用std::wstring。在这种情况下,使用st

我问了一个代码片段,其中包含一个unicode文本,将另一个unicode文本连接到第一个unicode文本,然后输出结果

另外,这段代码将帮助我解决unicode的另一个更大的问题。但在这之前,关键是完成我的要求


添加:顺便说一句,当我运行可执行文件时,我不能在命令行中写入任何unicode符号。我应该怎么做?这取决于操作系统。如果您的操作系统理解,您可以简单地将UTF-8序列发送给它。

取决于您所指的unicode类型。我想你的意思是你只是在使用
std::wstring
。在这种情况下,使用
std::wcin
std::wcout

对于编码之间的转换,您可以使用操作系统函数,如Win32:
WideChartMultiByte
MultiByteToWideChar
,或者如果您有实际文本(即逻辑字符字符串),则可以使用库,如,然后插入到宽流中。宽流将自动对字符进行编码,以匹配区域设置编码所需的位。(如果您使用的是编码比特,则流将对比特进行解码,然后重新编码以匹配区域设置。)


如果您知道有UTF编码的位(即,打算解码为逻辑字符字符串的位数组),并且您知道输出流的目标期望相同的位格式,那么您可以跳过解码和重新编码步骤,按原样写入()位。只有当您知道双方都使用相同的编码格式时,这种方法才有效,这可能适用于不打算与其他地区的进程通信的小型实用程序。

我过去也遇到过类似的问题,在我的例子中,
imbue
sync_with_stdio
成功了。试试这个:

#include <iostream>
#include <locale>
#include <string>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    wcin.imbue(locale("en_US.UTF-8"));
    wcout.imbue(locale("en_US.UTF-8"));

    wstring s;
    wstring t(L" la Polynésie française");

    wcin >> s;
    wcout << s << t << endl;
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main(){
ios_base::与_stdio同步(false);
wcin.imbue(地区(“en_US.UTF-8”);
wcout.imbue(语言环境(“en_US.UTF-8”);
WSTS环;
wstring t(L“法国的波利尼西亚”);
wcin>>s;

wcout这里的示例显示了四种不同的方法,其中只有第三种(C
conio
)和第四种(本机Windows API)有效(但只有在stdin/stdout未重定向的情况下)。请注意,您仍然需要包含要显示的字符的字体(Lucida Console至少支持希腊文和西里尔文)。请注意,这里的所有内容都是完全不可移植的,只是没有可移植的方式在终端上输入/输出Unicode字符串

#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'\n';
    _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);
}
#ifndef UNICODE
#定义UNICODE
#恩迪夫
#ifndef\u UNICODE
#定义UNICODE
#恩迪夫
#定义严格
#定义NOMINMAX
#定义WIN32_精益_和_平均值
#包括
#包括
#包括
#包括
#包括
#包括
void testIostream();
void testStdio();
void testConio();
void testWindows();
int wmain(){
testIostream();
testStdio();
testConio();
testWindows();
标准::系统(“暂停”);
}
void testIostream(){
std::wstring第一,第二;
std::getline(std::wcin,第一);
如果(!std::wcin.good())返回;
std::getline(std::wcin,第二);
如果(!std::wcin.good())返回;


std::wcout,在这一点上,如果您的操作系统理解,您可以使用UTF-16而不是UTF-8。+1:wcout表示wchar\u t的wstring(主要是窗口的UTF-16),cout表示char的string(默认情况下是Linux,UTF-8)@Philipp:
wcin
wcout
在哪些方面不适用于您?它们不会显示控制台字体不支持的Unicode字符,但这是控制台的错误,而不是iostreams。@Ben Voight:即使字体支持Unicode字符,它们也不会显示。请参阅我的答案,以获取示例。原因是它们没有包装
ReadConsoleW
/
WriteConsoleW
。Unicode不够精确。您使用的是UTF-[8/16/32]?是否要在内部以及序列化为文件时使用相同的表示形式?如果要转换表示形式,是否要手动转换或通过区域设置使用codecvt facet转换?如您所愿!!!没有文件,没有其他内容,仅此而已!在阅读了有关此主题的各种线程后,我的结论是它是imp在C++中,可以从C++和C标准中删除代码> CIN>代码> CUT//>代码,使用普通的Windows函数<代码> RealCopsOuts< /Code >和 Wr.EnguloSoo> <代码>。C++和C++标准在这方面只是被打破了。@菲利普- C++标准根本没有地址Unicode。就像DOE一样。Sn:地址不是与网络层通信。C++ 0x以某种方式我还没有熟悉Unicode。在这一点上,你将有标准的C++功能来做Unicode的东西。虽然C++不知道WTF是“控制台”。我打赌它会被处理好的。我已经调试过了,这一行就是问题所在:wcin.imbue(locale(“en_US.UTF-8”))是的,我确实测试了代码。它在我的Ubuntu上运行没有问题。你有什么系统?
wcin
wcout
在Windows上不工作,就像等效的C函数一样。只有本机API工作。谢谢。你的技巧解决了我的问题(如果输入包含重音字母,则跳过cin)他在使用UTF-16的Windows上,但需要特殊的API函数(
ReadConsole
/
WriteConsole
)使用Unicode文本。Windows上没有本地编码,因此宽流不起作用。谢谢。请告诉我如何使用Unicode在命令行中编写?我不能!它会忽略并使用拉丁语编写。此外,您可能希望编写“main”而不是“wmain”,否?如果您想阅读命令行参数,请将
wmain
声明为
int-wmain(int-argc,wchar\u t**argv)
w
不是打字错误!)。不,无论如何,我不能在命令行中输入任何来自亚美尼亚或俄罗斯字母的该死字母!您尝试了什么?顺便说一句,我认为您最好问一个新问题,th