当前位置: 首页 > 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,则可能引入额外的兼容性问题,如小数点不再始终是".",而必须通过lconv()->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"等方式触发字符串类型字段转换

相关文章:

  • transformer架构的语言模型保存的内容与格式详解
  • 【Maven】-- Maven Scope 详解
  • 【一文入门】shell语法进阶篇
  • 鸿蒙next 点击穿透实现
  • org.springframework.boot不存在的其中一个解决办法
  • JAVA面试_进阶部分_Linux面试题
  • Idea 中 Project Structure简介
  • java23种设计模式-中介者模式
  • vue打印页面(可分页、可打印echarts、可显示背景色)
  • Qwen 2.5 技术报告解读
  • leetcode151 反转字符串中的单词
  • Spring Boot 中 @Transactional 注解全面解析
  • MySQL中json类型数据查询
  • 线性回归(一)基于Scikit-Learn的简单线性回归
  • DeepSeek + Higress AI 网关/Spring AI Alibaba 案例征集
  • 博云先进算力管理平台AIOS已上线全尺寸DeepSeek系列模型
  • 15.代码随想录算法训练营第十五天|(递归)110. 平衡二叉树,257. 二叉树的所有路径*,404. 左叶子之和,222.完全二叉树的节点个数[打卡自用]
  • JavaWeb-ServletContext应用域接口
  • Codeforces Round 1006 (Div. 3)(部分题解)
  • 图神经网络:拓扑数据分析的新时代
  • 外交部:对伊朗拉贾伊港口爆炸事件遇难者表示深切哀悼
  • 报告显示2024年全球军费开支增幅达冷战后最大
  • 科学时代重读“老子”的意义——对谈《老子智慧八十一讲》
  • 清华姚班,正走出一支军团
  • 四川苍溪县教育局通报“工作人员辱骂举报学生”:停职检查
  • 美国政府将暂时恢复部分受影响留学生的合法身份,并将制订新标准