MSVC下快速Unicode I/O

本文介绍如何使用_setmode API快速改变文件输出编码,支持UTF-8和UTF-16编码,适用于需要输出非ASCII字符的宽字符串场景。

http://blog.kingsamchen.com/archives/863


如果需要往console输出包含非ASCII字符的宽字符串,一个比较快速的方法是使用WriteConsoleW这个API。

如果想兼容crt和STL的方式,例如使用wprintfstd::wcout,则可以用另一种快速的方法:使用_setmode来改变底层的translation mode。

参考文档可以看这里_fileno从一个FILE*得到对应的file descriptor,第二个参数指定目标模式。

对比其他需要设置locale的方法(要么通过setlocale,要么通过STL的imbue),前者很容易一个不小心就把其他设置也连着一块给改了;后者经常忘了怎么用。

额外福利

第二个参数还可以使用_O_U8TEXT,这样系统I/O的时候会自动将wide-string转换成utf-8编码的字符串。利用_fileno获取目标文件的描述符,则可以将宽字符直接以utf-8编码的方式输出到目标文件。

不过由于没有靠谱的方法从std::fstream中获取FILE*,所以这种方式的文件I/O不能使用STL的相关设施。

–EOF–

无论使用_O_U8TEXT还是_O_U16TEXT,源字符串都必须是宽字符串,系统会在IO的时候根据需要做自动的编码转换。

这种设计看起来比较吻合Windows现在的,以UTF-16/wide-string为内部编码,需要时(主要是涉及到文件I/O等)转换为其他编码思路。

C++11虽然已经开始提供各种utf编码标准设施,但是utf-8编码的字符串仍然要以u8为前缀,虽然现在VS2013以及VS14都没有迹象表明要支持这个特性,但是这个proposal起码不会破坏MSVC的原始行为,至少为未来实现留下一点可能。至于什么时候能用上这个设施,就看VS团队了。


转载于:https://www.cnblogs.com/lgh1992314/p/5834777.html

* 正在执行任务: E:\Qt5.9.6\Tools\QtCreator\bin\jom.exe clean jom 1.1.2 - empower your cores E:\Qt5.9.6\Tools\QtCreator\bin\jom.exe -f Makefile.Release clean del release\moc_predefs.h del release\moc_widget.cpp del ui_widget.h del release\main.obj release\widget.obj release\moc_widget.obj 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\release\main.obj del release\MyTest.exp 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\release\MyTest.exp E:\Qt5.9.6\Tools\QtCreator\bin\jom.exe -f Makefile.Debug clean del debug\moc_predefs.h 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\debug\moc_predefs.h del debug\moc_widget.cpp del ui_widget.h 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\debug\moc_widget.cpp 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\ui_widget.h del debug\main.obj debug\widget.obj debug\moc_widget.obj 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\debug\main.obj del debug\MyTest.exp debug\MyTest.vc.pdb debug\MyTest.ilk debug\MyTest.idb 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\debug\MyTest.exp del MyTest.exp 找不到 C:\Users\Administrator\Desktop\Qt\MyTest\MyTest.exp * 终端将被任务重用,按任意键关闭。 * 正在执行任务: E:\Qt5.9.6\5.9.6\msvc2017_64\bin\qmake.exe C:\Users\Administrator\Desktop\Qt\MyTest/MyTest.pro -spec win32-msvc * 终端将被任务重用,按任意键关闭。 * 正在执行任务: E:\Qt5.9.6\Tools\QtCreator\bin\jom.exe -f Makefile.Release jom 1.1.2 - empower your cores E:\Qt5.9.6\5.9.6\msvc2017_64\bin\uic.exe widget.ui -o ui_widget.h cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc -DUNICODE -D_UNICODE -DWIN32 -DWIN64 -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -I. -IE:\Qt5.9.6\5.9.6\msvc2017_64\include -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtWidgets -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtGui -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtANGLE -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtCore -Irelease -I. -IE:\Qt5.9.6\5.9.6\msvc2017_64\mkspecs\win32-msvc -Forelease\ @C:\Users\ADMINI~1\AppData\Local\Temp\main.obj.18884.16.jom cl -BxE:\Qt5.9.6\5.9.6\msvc2017_64\bin\qmake.exe -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E E:\Qt5.9.6\5.9.6\msvc2017_64\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h main.cpp E:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\cstddef(7): fatal error C1083: 无法打开包括文件: “stddef.h”: No such file or directory cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc -DUNICODE -D_UNICODE -DWIN32 -DWIN64 -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -I. -IE:\Qt5.9.6\5.9.6\msvc2017_64\include -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtWidgets -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtGui -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtANGLE -IE:\Qt5.9.6\5.9.6\msvc2017_64\include\QtCore -Irelease -I. -IE:\Qt5.9.6\5.9.6\msvc2017_64\mkspecs\win32-msvc -Forelease\ @C:\Users\ADMINI~1\AppData\Local\Temp\widget.obj.18884.32.jom widget.cpp E:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\cstddef(7): fatal error C1083: 无法打开包括文件: “stddef.h”: No such file or directory jom: C:\Users\Administrator\Desktop\Qt\MyTest\Makefile.Release [release\main.obj] Error 2 E:\Qt5.9.6\5.9.6\msvc2017_64\bin\moc.exe -DUNICODE -D_UNICODE -DWIN32 -DWIN64 -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG --compiler-flavor=msvc --include release/moc_predefs.h -IE:/Qt5.9.6/5.9.6/msvc2017_64/mkspecs/win32-msvc -IC:/Users/Administrator/Desktop/Qt/MyTest -IE:/Qt5.9.6/5.9.6/msvc2017_64/include -IE:/Qt5.9.6/5.9.6/msvc2017_64/include/QtWidgets -IE:/Qt5.9.6/5.9.6/msvc2017_64/include/QtGui -IE:/Qt5.9.6/5.9.6/msvc2017_64/include/QtANGLE -IE:/Qt5.9.6/5.9.6/msvc2017_64/include/QtCore -I"E:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include" -I"E:\Windows Kits\10\Include\10.0.19041.0\um" -I"E:\Windows Kits\10\Include\10.0.19041.0\shared" widget.h -o release\moc_widget.cpp jom: C:\Users\Administrator\Desktop\Qt\MyTest\Makefile.Release [release\widget.obj] Error 2 * 终端进程“C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command E:\Qt5.9.6\Tools\QtCreator\bin\jom.exe -f Makefile.Release”已终止,退出代码: 1。为什么?
最新发布
07-29
#tasks.json { "version": "2.0.0", "tasks": [ { "label": "C++: cl.exe build with MySQL", "type": "shell", "command": "cmd.exe", "args": [ "/c", "\"call E:\\Visual_Studio_2022\\VC\\Auxiliary\\Build\\vcvars64.bat &&", "E:\\Visual_Studio_2022\\VC\\Tools\\MSVC\\14.44.35207\\bin\\Hostx64\\x64\\cl.exe\"", "/EHsc", "/std:c++17", "/I", "E:\\MySQL\\mysql connector c++ 8.4.0 winx64\\include", "/I", "E:\\MySQL\\mysql connector c++ 8.4.0 winx64\\include\\jdbc", "\"${fileDirname}\\test.cpp\"", "/Fe:\"${fileDirname}\\test_mysql.exe\"", "/link", "/LIBPATH:E:\\MySQL\\mysql connector c++ 8.4.0 winx64\\lib64", "mysqlcppconn8-2-vs14.lib" ], "options": { "cwd": "${fileDirname}", "shell": { "executable": "cmd.exe", "args": ["/c"] } }, "problemMatcher": ["$msCompile"], "group": { "kind": "build", "isDefault": true } } ] } #c_cpp_properites { "configurations": [ { "name": "Win32-MSVC", "includePath": [ "${workspaceFolder}/**", "E:/MySQL/mysql connector c++ 8.4.0 winx64/include/jdbc/", "E:/MySQL/mysql connector c++ 8.4.0 winx64/include", "E:/Visual_Studio_2022/VC/Tools/MSVC/14.44.35207/include", "C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/ucrt", "C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/shared", "C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/um", "C:/Program Files (x86)/Windows Kits/10/Include/10.0.26100.0/winrt" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE", "_CRT_SECURE_NO_WARNINGS" ], "compilerPath": "E:/Visual_Studio_2022/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "windows-msvc-x64", "compilerArgs": [ "/EHsc", "/permissive-" ], "configurationProvider": "ms-vscode.makefile-tools" } ], "version": 4 }怎么修改
05-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值