c++ - C++ 中的 Unicode 问题,但不是 C

标签 c++ c unicode utf-8

我正在尝试在 Windows 上用 C++ 将 unicode 字符串写入屏幕。我将控制台字体更改为 Lucida Console 并将输出设置为 CP_UTF8 aka 65001。

我运行以下代码:

#include <stdio.h>  //notice this header file..
#include <windows.h>
#include <iostream>

int main()
{
    SetConsoleOutputCP(CP_UTF8);
    const char text[] = "Россия";
    printf("%s\n", text);
}

打印出来就好了!

但是,如果我这样做:

#include <cstdio>  //the C++ version of the header..
#include <windows.h>
#include <iostream>

int main()
{
    SetConsoleOutputCP(CP_UTF8);
    const char text[] = "Россия";
    printf("%s\n", text);
}

它打印:������������

我不知道为什么..

另一件事是当我这样做时:

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

int main()
{
    std::uint32_t oldcodepage = GetConsoleOutputCP();
    SetConsoleOutputCP(CP_UTF8);

    std::string text = u8"Россия";
    std::cout<<text<<"\n";

    SetConsoleOutputCP(oldcodepage);
}

我得到与上面相同的输出(非工作输出)。

std::string 上使用 printf,它可以正常工作:

#include <stdio.h>
#include <windows.h>
#include <iostream>

int main()
{
    std::uint32_t oldcodepage = GetConsoleOutputCP();
    SetConsoleOutputCP(CP_UTF8);

    std::string text = u8"Россия";
    printf("%s\n", text.c_str());

    SetConsoleOutputCP(oldcodepage);
}

但前提是我使用 stdio.h 而不是 cstdio

知道如何使用 std::cout 吗?我怎样才能使用 cstdio 以及? 为什么会这样? cstdio 不就是 stdio.h 的 c++ 版本吗?

编辑:我刚刚尝试过:

#include <iostream>
#include <io.h>
#include <fcntl.h>

int main()
{
    _setmode(_fileno(stdout), _O_U8TEXT);
    std::wcout << L"Россия" << std::endl;
}

是的,它有效,但前提是我使用 std::wcoutwide strings。我真的很想避免 wide-strings 到目前为止我看到的唯一解决方案是 C-printf :l

所以问题仍然存在..

最佳答案

虽然您已将控制台设置为期望 UTF-8 输出,但我怀疑您的编译器将字符串文字视为其他字符集中。我不知道为什么 C 编译器的行为不同。

好消息是 C++11 包含对 UTF-8 的一些支持,并且微软已经实现了标准的相关部分。代码有点复杂,但您需要查看 std::wstring_convert (与 UTF-8 相互转换)和 <cuchar> 标题。

您可以使用这些函数将其转换为 UTF-8,并假设您的控制台需要 UTF-8,一切应该可以正常工作。

就个人而言,当我需要调试这样的东西时,我经常将输出定向到文本文件。文本编辑器似乎比 Windows 控制台更好地处理 Unicode。就我而言,我经常正确输出代码点,但控制台设置不正确,所以我最终还是会打印垃圾。


我可以告诉你,这在 Linux(使用 Clang)和 Windows(使用 GCC 4.7.3 和 Clang 3.5)中都适用;你需要在命令行中添加“std=c++11”才能编译GCC 或 Clang):

#include <cstdio>

int main()
{
    const char text[] = u8"Россия";
    std::printf("%s\n", text);
}

使用 Visual C++(2012,但我相信它也适用于 2010),我不得不使用:

#include <codecvt>
#include <cstdio>
#include <locale>
#include <string>

int main()
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    auto text = converter.to_bytes(L"Россия");
    std::printf("%s\n", text.c_str());
}

关于c++ - C++ 中的 Unicode 问题,但不是 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21370710/

相关文章:

c++ - 在使用 Bazel 构建的应用程序中访问运行时文件

c++ - GL上下文销毁

c - C 中 fprintf 的通用参数

unicode - 实际使用中最常见的非 BMP Unicode 字符有哪些?

php - 允许空格、unicode 字母、数字、下划线、破折号和逗号吗?

c++ - 全局声明的数据结构有多大?

c++ - 从 makefile 运行程序

c - 管理日志文件大小

c - 如何检查变量是否等于单词

MySQL 无法对表情符号正确进行 GROUP BY