当前位置: 首页 > news >正文

Windows下不建议使用C/C++运行库的本地化功能

Windows不建议setlocale或使用C++的std::locale对象等C/C++运行库的本地化功能,因为setlocale或C++的std::locale对象实现bug多,不稳定,可能存在兼容性问题,如:

1、DOS/Win16下setlocale只支持"C"的locale

2、Win32下如使用可移植的""获取环境locale,在UCRTv1803之前会获取到user locale(区域设置:标准和格式)对应的ANSI代码页,而不是system locale(高级:非Unicode程序的语言)对应的ANSI代码页,作为locale相关函数的代码页,而A结尾的WinAPI和mkdir等很多C/C++运行库函数大多使用后者,当两者不匹配时会发生乱码;微软文档中提供的不可移植的".ACP"、".OCP"也是一样的问题,但是UCRTv1803没跟着""改过来;唯一在所有版本运行库都可以正常工作的方法是使用sprintf(buf, ".%u", GetACP()); setlocale(LC_CTYPE, buf);,这也是个不可移植的方法

3、setlocale/std::locale在UCRTv1803之前不支持UTF-8代码页,但UCRTv1803之后setlocale或std::locale(配合较新版本的MSVC编译器)可使用".utf[-]8"支持UTF-8代码页,它不仅会使得UTF-8作为locale相关函数的代码页,同时会使mkdir等C/C++运行库函数也改为使用UTF-8代码页,但并不改变GetACP()返回的代码页和A结尾的WinAPI使用的代码页,有可能会造成额外的兼容性问题

4、如果使用LC_ALL而不是LC_CTYPE,则可能引入额外的兼容性问题,如小数点不再始终是".",而必须通过localeconv()->decimal_point/_W_decimal_point获取,C++更是会加上千位分隔符,兼容性问题更大

5、微软C/C++运行库中setlocale/std::locale剩下的用法均不可移植,且每一代运行库之间行为并不稳定,代码页也是跟随locale而不是跟随系统,并且在UCRTv1803之前不支持UTF-8,即使研究清楚了,也会陷入行为不稳定的陷阱

6、频繁切换setlocale会造成线程安全问题,_locale_t、_configthreadlocale等解决方案更麻烦、更不可移植、更少人使用且bug更多

7、C/C++运行库遇到非法字符默认会截断并返回错误/抛出异常,和Win32的标准用户体验替换为"?"或U+FFFD(菱形方块问号)不同

8、MinGW(包括MinGW32和MinGW-w64)的C++标准库的std::locale不支持"C"以外的locale

建议在Windows下的C/C++程序:

1、不要setlocale、构造std::locale对象,可能会造成兼容性问题或行为不稳定,也不要依赖_locale_t、_configthreadlocale等更麻烦、更不可移植、更少人使用且bug更多的方法

2、使用C/C++运行库进行字符编码转换,使用MultiByteToWideChar/WideCharToMultiByte、AnsiToOem/OemToAnsi/AnsiToOemBuff/OemToAnsiBuff(不可移植但稳定)或第三方库(可移植)进行字符编码转换

3、不要使用C/C++运行库进行本地化,使用Windows National Language Support API(不可移植但稳定)或第三方库(可移植)进行本地化

4、如果必须使用C/C++运行库的字符串函数,和字节流有关的如printf/wprintf只能用char版本的printf,和文件名等WinAPI字符串有关的如fopen/_wfopen尽量用wchar_t版本的_wfopen(如果为了可移植可以用char版本的fopen),和字符串本身有关的如snprintf/swprintf根据字符串本身决定使用char还是wchar_t版本,且不要通过"%ls"、"%hs"等方式触发字符串类型字段转换


http://www.mrgr.cn/news/92543.html

相关文章:

  • 计算机工具基础(五)——Vim
  • KubeKey一键安装部署k8s集群和KubeSphere详细教程
  • Android移动应用开发实践-1-下载安装和简单使用Android Studio 3.5.2版本(频频出错)
  • 数据开发面试:DQL,DDL,DTL
  • 初会学习记录
  • 【射频仿真学习笔记】Cadence的Layout EXL与ADS dynamic link联动后仿
  • Harmony开发笔记(未完成)
  • 【JAVA-数据结构】Map和Set
  • 30 分钟从零开始入门 CSS
  • DeepSeek R1 + 飞书机器人实现AI智能助手
  • spring结合mybatis多租户实现单库分表
  • C语言机试编程题
  • <tauri><rust><GUI><PLC>基于tauri,编写一个串口485调试助手
  • thinkphp下的Job队列处理
  • Windows版FFmpeg使用及B站视频下载示例python源码
  • 最新版 (持续更新)docker 加速源 linux yum 源
  • 001 Kafka入门及安装
  • 弱监督语义分割学习计划(1)-简单实现Open Vocabulary Label但是效果不好
  • Vue 3 搭建前端模板并集成 Ant Design Vue(2025)
  • 编写Redis开机自启动脚本