最直接的方式是调用 setlocale(LC_ALL, nullptr) 获取当前 C locale 字符串,但线程不安全且返回值短暂有效;推荐用 std::locale().name() 获取 C++ 默认 locale 名称,或跨平台结合环境变量(LANG)、Windows API(GetUserDefaultUILanguage)等多源判断系统界面语言。

用 setlocale 获取当前区域设置(C 风格)
最直接的方式是调用 C 标准库的 setlocale,传入 LC_ALL 或更具体的类别(如 LC_MESSAGES),返回当前生效的 locale 字符串:
-
setlocale(LC_ALL, nullptr)返回当前 C locale 的名称(如"en_US.UTF-8"或"Chinese_China.936"),不修改任何设置 - 注意:该函数线程不安全;多线程中应优先用
uselocale+newlocale(但仅限 POSIX 系统) - Windows 下返回格式可能为
"Chinese_China.936",Linux/macOS 通常为"zh_CN.UTF-8"—— 解析时需兼容不同分隔符(_、.、-) - 返回值为
const char*,不可修改,也不保证长期有效(下次调用setlocale可能使其失效)
用 std::locale 获取 C++ 默认 locale(推荐用于格式化)
std::locale() 构造默认 locale 时会读取系统环境,但它不提供原始字符串,而是封装了 facet(如 std::ctype、std::collate)用于实际操作:
-
std::locale().name()可返回 locale 名称(如"en_US.UTF-8"),但某些标准库实现(如 MSVC 的旧版本)可能返回"*"或空字符串 - 若只需判断语言是否为中文,更可靠的做法是检查
std::locale().facet<std::ctype<char>>().is(std::ctype_base::alpha, '中')是否成立(需确保 locale 支持该字符) - 不要依赖
std::locale("").name()—— 空字符串参数在部分平台触发异常或 fallback 到"C"
跨平台获取语言代码(LANG / GetUserDefaultUILanguage)
真正想获取“系统界面语言”(如 en-US、zh-CN),不能只靠 locale,因为 locale 可被用户显式修改,而 UI 语言是独立设置:
- Linux/macOS:读取环境变量
LANG(getenv("LANG")),fallback 到LC_MESSAGES;注意值可能含编码后缀(.UTF-8),需截断 - Windows:调用
GetUserDefaultUILanguage()(windows.h),返回 LANGID(如0x0804表示简体中文),再用GetLocaleInfoEx转成 BCP 47 标签("zh-CN") - macOS:用
CFBundleGetLocalizationForLanguage或NSUserDefaults读AppleLanguages数组首项 - Qt 或 wxWidgets 等框架有封装好的接口(如
QLocale::system().bcp47Name()),比裸 API 更省心
常见坑:locale 名称 ≠ 语言代码,且无法直接映射
拿到 "zh_CN.UTF-8" 不等于语言就是 "zh-CN" —— 某些嵌入式系统或容器环境 locale 可能设为 "C",但 UI 语言仍是中文;反之,locale 设为 "ja_JP" 时,GetUserDefaultUILanguage 在 Windows 上仍可能返回英文 ID。
立即学习“C++免费学习笔记(深入)”;
- 没有标准函数能把所有 locale 字符串无歧义转成 IETF BCP 47 标签(如
zh-Hans-CN) -
setlocale(LC_ALL, "")会尝试从环境变量初始化,但失败时静默 fallback 到"C",不报错也不提示 - Windows 控制面板里“区域和语言”设置的“格式”和“管理”选项卡分别影响不同 locale 类别,
LC_TIME和LC_MONETARY可能不一致
真要可靠识别用户意图,得组合多个来源:环境变量 + 系统 API + 用户配置文件,再加 fallback 规则。单靠一个接口永远不够。


















