如何在 Windows 上将 UTF-8 字符串打印到 std::cout?

2023-12-03

我正在用 C++ 编写一个跨平台应用程序。所有字符串均在内部进行 UTF-8 编码。考虑以下简化代码:

#include <string>
#include <iostream>

int main() {
    std::string test = u8"Greek: αβγδ; German: Übergrößenträger";
    std::cout << test;

    return 0;
}

在 Unix 系统上,std::cout期望 8 位字符串采用 UTF-8 编码,因此此代码可以正常工作。

然而,在 Windows 上,std::cout期望 8 位字符串采用 Latin-1 或类似的非 Unicode 格式(取决于代码页)。这将导致以下输出:

希腊语:╬▒╬▓╬│╬┤;德语: ├£bergr├Â├ςentr├ñger

我能做些什么来使std::cout在 Windows 上将 8 位字符串解释为 UTF-8?

这是我尝试过的:

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

int main() {
    _setmode(_fileno(stdout), _O_U8TEXT);
    std::string test = u8"Greek: αβγδ; German: Übergrößenträger";
    std::cout << test;

    return 0;
}

我本来希望_setmode就可以了。但是,这会导致调用行中出现以下断言错误operator<<:

Microsoft Visual C++ 运行时库

调试断言失败!

程序:d:\ Visual Studio 2015 \ Projects \ utf8test \ Debug \ utf8test.exe 文件:minkernel\crts\ucrt\src\appcrt\stdio\fputc.cpp 线路:47

表达式: ( (_Stream.is_string_backed()) || (fn = _fileno(_Stream.public_stream()), ((_textmode_safe(fn) == __crt_lowio_text_mode::ansi) && !_tm_unicode_safe(fn))))

有关您的程序如何引发断言的信息 失败,请参阅有关断言的 Visual C++ 文档。


最后,我成功了。这个答案结合了 Miles Budnek、Paul 和 mkluwe 的意见以及我自己的一些研究。首先,让我从可在 Windows 10 上运行的代码。之后,我将引导您完成代码并解释为什么它不能在 Windows 7 上开箱即用。

#include <string>
#include <iostream>
#include <Windows.h>
#include <cstdio>

int main() {
    // Set console code page to UTF-8 so console known how to interpret string data
    SetConsoleOutputCP(CP_UTF8);

    // Enable buffering to prevent VS from chopping up UTF-8 byte sequences
    setvbuf(stdout, nullptr, _IOFBF, 1000);

    std::string test = u8"Greek: αβγδ; German: Übergrößenträger";
    std::cout << test << std::endl;
}

代码首先设置代码页,正如迈尔斯·布德尼克所建议的。这将告诉控制台将其接收到的字节流解释为 UTF-8,not作为 ANSI 的一些变体。

接下来,Visual Studio自带的STL代码有问题。std::cout将其数据打印到 type 的流缓冲区std::basic_filebuf。当该缓冲区接收到一个字符串时(通过std::basic_streambuf::sputn()),它不会将其作为一个整体传递给底层文件。相反,它将单独传递每个字节。正如 mkluwe 所解释的,如果控制台接收到 UTF-8 字节序列作为单独的字节,它不会将它们解释为单个代码点。相反,它会将它们视为多个字符。 UTF-8 字节序列中的每个字节本身都是无效的代码点,因此您会看到 �。有Visual Studio 的相关错误报告,但它被关闭为“按设计”。解决方法是启用流缓冲。作为额外的好处,这将为您带来更好的性能。但是,您现在可能需要像我一样定期刷新流std::endl,否则您的输出可能不会显示。

最后,Windows 控制台支持光栅字体和 TrueType 字体。正如保罗所指出的,光栅字体将简单地忽略控制台的代码页。因此,仅当控制台设置为 TrueType 字体时,非 ASCII Unicode 字符才有效。在 Windows 7 之前,默认字体是光栅字体,因此用户必须手动更改它。幸运的是,Windows 10 将默认字体更改为 Consolas,所以这部分问题应该随着时间的推移自行解决。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Windows 上将 UTF-8 字符串打印到 std::cout? 的相关文章

  • Poco c++Net:Http 从响应中获取标头

    我使用 POCO C Net 库进行 http 我想尝试制定持久缓存策略 首先 我认为我需要从缓存标头中获取过期时间 并与缓存值进行交叉检查 如果我错了 请告诉我 那么我如何从中提取缓存头httpResponse 我已经看到你可以用 Jav
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 是否存在指向不同类型的指针具有不同大小的平台?

    C 标准允许指向不同类型的指针具有不同的大小 例如sizeof char sizeof int 是允许的 但是 它确实要求如果将指针转换为void 然后转换回其原始类型 它必须与其原始值进行比较 因此 从逻辑上来说 sizeof void
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • 在 asp.net MVC 中使用活动目录进行身份验证

    我想使用活动目录对我的 asp net mvc 项目中的用户进行身份验证 在网上冲浪了几个小时后 我没有找到任何对我有用的东西 我已经看到了所有结果 但什么也没有 我尝试按照许多帖子的建议编辑我的 web config 如果有人可以帮助我提
  • 使用具有抗锯齿功能的 C# 更改抗锯齿图像的背景颜色

    我有一个图像需要更改背景颜色 例如 将下面示例图像的背景更改为蓝色 然而 图像是抗锯齿的 所以我不能简单地用不同的颜色替换背景颜色 我尝试过的一种方法是创建第二个图像 仅作为背景 并更改其颜色并将两个图像合并为一个图像 但是这不起作用 因为
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • 逆向工程 ASP.NET Web 应用程序

    我有一个 ASP NET Web 应用程序 我没有源代码 该 bin 包含 10 个程序集和一个 compiled 文件 我在 App Code dll 上使用 Reflector 它向我显示了类和命名空间之类的东西 但它太混乱了 有没有什
  • LINQ 中的“from..where”或“FirstOrDefault”

    传统上 当我尝试从数据库中获取用户的数据时 我使用了以下方法 在某种程度上 DbUsers curUser context DbUsers FirstOrDefault x gt x u LoginName id string name c
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc

随机推荐

  • Openshift node.js 成功部署,但“应用程序不可用”

    我在让 Node js 应用程序在 Openshift 上运行时遇到问题 我已经将 openshift 项目设置为从 git 存储库中提取 My server listen调用是这样的 var port process env OPENSH
  • 禁用延迟加载时出现“操作无法完成,因为 DbContext 已被释放”异常

    Given public ActionResult List using var unitOfWork new UnitOfWork var result unitOfWork Repository Find
  • Angular:TypeScript 表中的搜索栏

    我已经完成了一个简单的 CRUD 应用程序 现在我必须添加一个搜索栏来过滤我的表格并显示与我数字相同的字母的行 我不知道在我的组件中要做什么 我看到管道和过滤器有不同的东西 但我无法使它们适应我的项目 我想知道是否有一种方法可以在我的 co
  • 在提交和结帐中启用密码

    我根据这个资源设置了一个svn存储库http anandafit info 2010 11 03 setup a subversion server 但是当我只提交代码时 服务器询问用户名和密码 而不询问 svn 签出过程的密码 似乎我没有
  • CSS - Chrome 移动设备上出现带有剪辑路径的奇怪边框

    我使用了基本的 CSSclip path创建一个 斜坡 如下所示 问题是 在移动设备上使用 Chrome 浏览器会创建一个在我的 CSS 中未定义的 边框 奇怪的是 在桌面版 Chrome 和 Firefox 桌面 移动 上它不会出现 我仔
  • 使用 doxygen 扩展 makefile 以生成库和文档

    我已经实现了一个二叉树程序 其中包括带有函数的tree c 带有它们的声明的tree h以及用于测试的main c 另外 我有一个 makefile 它是 CC gcc CFLAGS g Wall DEPS tree h OBJ main
  • ASP.NET MVC 2 和 IIS 7.0 的错误处理

    再会 我最近从 IIS 6 0 切换到 IIS 7 x 并且正在寻找我梦想中的 ASP NET MVC 2 错误处理技术 我想要实现的目标 在一个地方处理所有未处理的异常 最好在 Global asax 处理程序中 404 和 403 错误
  • 如何在 bash 中有条件地添加管道元素

    我需要形成各种命令的管道 管道的某些元素或元素序列仅在某些条件成立时才相关 现在 我可以写 if whatever then cmd1 cmd2 cmd3 cmd4 else cmd1 cmd4 fi 但这意味着重复cmd1 and cmd
  • 如何使用 jq 根据内部数组中的值过滤对象数组?

    鉴于此输入 Id cb94e7a42732b598ad18a8f27454a886c1aa8bbba6167646d8f064cd86191e2b Names condescending jones loving hoover Id 186
  • css 选择器:第一个子元素

    div li first child 上面的CSS选择器的目标是什么 页面上每个 div 的第一个 li or div 的所有后代 li 其中 div 是其父级的第一个子级 The first child适用于li 应该选择lis 是任何
  • 非常不寻常的 Xcode 编译行为

    自从 Xcode 6 1 和 iOS 8 1 发布以来 我的一个应用程序停止运行 仅当我使用 发布 而不是 调试 方案在设备上执行 运行 时 我才设法重现该问题 现在来说说问题 这在调试模式下工作正常 import Foundation c
  • 如何解决 ASP.NET 中全局文件中的 Ninject 依赖关系?

    我正在将 Ninject 和 Ninject Web 程序集与 Web 表单应用程序一起使用 在 global asax 文件中 我指定了如下绑定 public class Global NinjectHttpApplication pro
  • 并发修改异常

    通过下面的代码片段 我尝试处理电子表格 但需要排除临时列 我知道我这样做的粗略方式 将异常放入 ArrayList 并处理每个列表 并且在当前行列上不断增量是不正当的 但你知道只是完成它 但是我收到了标题错误 我相信这种情况永远不会发生 我
  • 如何格式化数字 0..9 以显示 2 位数字(不是日期)

    我希望始终显示 100 以下的 2 位数字 例如 03 05 15 如何在不使用条件来检查 0 是否低于 10 的情况下附加 0 我需要将结果附加到另一个字符串 所以我不能使用 printf 您可以使用 String format 02d
  • SpriteKit - SKScene 边界不等于 SKView 边界

    最近我创建了一个新的 Xcode 游戏项目 我没有碰任何东西就运行了模板 我期待一个标准你好世界 应用程序 但我注意到一件事 我得到的不是充满背景的场景 而是场景cut在顶部和底部 我怎样才能让它充满整个屏幕 看起来默认的 SpriteKi
  • Flask - 将反馈数据存储到服务器

    我使用烧瓶应用程序作为服务器 我只是返回用户交易 但是 如果交易错误 我需要允许用户向服务器提供反馈 from flask import Flask render template request import pandas as pd p
  • 使用 Angular.js 版本 1.2.18 进行嵌套过滤

    我是第一次尝试 AngularJS 我确实重复了一个基于 JSON 数据的模板 这是一个示例 scope users name first user status name employee name second user status
  • 删除 matplotlib 图上的图例

    要将图例添加到 matplotlib 图中 只需运行legend How to remove情节中的传奇 我最接近的是运行legend 为了从数据中清空图例 但这会在右上角留下一个丑陋的白色矩形 As of 绘图库v1 4 0rc4 a r
  • 有关 SOLR 文档等的问题

    网站 分类广告网站 用户可以投放广告 搜索广告等 我打算使用SOLR进行搜索 然后仅以ID nr s返回结果 然后使用这些ID nr s查询mysql 最后用这些ID s显示结果 目前我在 MySQL 中有大约 30 个表 每个类别一个 1
  • 如何在 Windows 上将 UTF-8 字符串打印到 std::cout?

    我正在用 C 编写一个跨平台应用程序 所有字符串均在内部进行 UTF 8 编码 考虑以下简化代码 include