C标准库的setlocale()用法笔记
转自:http://zyxhome.org/wp/cc-prog-lang/c-stdlib-setlocale-usage-note/
[在此向原文作者说声谢谢!若有读者看到文章转载时请写该转载地址,不要写我的BLOG地址。尊重他人的劳动成果 ^_^ ]
C 和 C++ 的标准库分别有自己的 locale 操作方法,C 标准库的 locale 设定函数是 setlocale(),而 C++ 标准库有 locale 类和流对象的 imbue() 方法。这篇是我自己的 setlocale() 使用总结。
Linux的glibc中的setlocale()
具体参考:man 3 setlocale
头文件与声明如下:
1 #include <locale.h>
2 char* setlocale(int category, const char* locale);
说明:
category:为locale分类,表达一种locale的领域方面,通常有下面这些预定义常量:LC_ALL、LC_COLLATE、LC_CTYPE、LC_MESSAGES、LC_MONETARY、LC_NUMERIC、LC_TIME,其中 LC_ALL 表示所有其它locale分类的并集。
locale:为期望设定的locale名称字符串,在Linux/Unix环境下,通常以下面格式表示locale名称:language[_territory][.codeset][@modifier],language 为 ISO 639 中规定的语言代码,territory 为 ISO 3166 中规定的国家/地区代码,codeset 为字符集名称。
在Linux下,可以使用 locale -a 命令查看系统中所有已配置的 locale。用不带选项的 locale 命令查看当前 Shell 中活动的 locale。用 locale -m 命令查看locale系统支持的所有可用的字符集编码。
和locale相关的包叫做:locales,locale系统支持的所有可用locale在文件:/usr/share/i18n/SUPPORTED 中列出。
在Debian下,可用 dpkg-reconfigure locales 命令重新配置 locale,也可以手工修改 /etc/locale.gen 文件,然后运行 locale-gen 命令。
在Ubuntu下,修改 /var/lib/locales/supported.d/local 文件,配置新的 locale,然后运行 locale-gen 命令。
当 locale 为 NULL 时,函数只做取回当前 locale 操作,通过返回值传出,并不改变当前 locale。
当 locale 为 "" 时,根据环境的设置来设定 locale,检测顺序是:环境变量 LC_ALL,每个单独的locale分类LC_*,最后是 LANG 变量。为了使程序可以根据环境来改变活动 locale,一般都在程序的初始化阶段加入下面代码:setlocale(LC_ALL, "")。
当C语言程序初始化时(刚进入到 main() 时),locale 被初始化为默认的 C locale,其采用的字符编码是所有本地 ANSI 字符集编码的公共部分,是用来书写C语言源程序的最小字符集(所以才起locale名叫:C)。
当用 setlocale() 设置活动 locale 时,如果成功,会返回当前活动 locale 的全名称;如果失败,会返回 NULL。
Windows的CRT中的setlocale()
具体参考:setlocale - MSDN Run-Time Library Reference
在 Windows CRT 的实现中还有一个使用 wchar_t 作为 locale 名的宽字符版本:_wsetlocale()。因此,也有了使用 _TCHAR 宏版本的 setlocale():_tsetlocale()。
Windows CRT 实现的 setlocale() 和 glibc 版本的头文件与声明相同,使用方法类似,如下:
支持的 locale 分类常量:LC_ALL、LC_COLLATE、LC_CTYPE、LC_MONETARY、LC_NUMERIC、LC_TIME。
请求设定的 locale 名可以为以下格式(参考MSDN:Language and Country/Region Strings):
lang[_country_region[.code_page]]:虽然形式与 glibc 的相同,当 Windows 的 locale 名并不符合 POSIX 的规范,比如采用 GBK 字符集的大陆中文,POSIX 的名字为:zh_CN.GBK,而在 Windows CRT 中要用:Chinese_People's Republic of China.936,(-_-^)。
lang 字段的可用值参考:Language Strings
country_region 字段的可用值参考:Country/Region Strings
code_page 字段的可用值是 Windows 系统支持的代码页编号,参考:Code Page Identifiers
.code_page:可以直接使用代码页来设定 locale,而且可以使用 .OCP、.ACP 两个伪代码页,.OCP 表示从系统获得的当前活动的 OEM 代码页,.ACP 表示从系统获得的活动 ANSI 代码页。
"":根据 Windows 系统环境的活动 ANSI 代码页来设定 locale。.OCP、.ACP、和环境代码页都受控制面板中“区域与语言选项”的设置影响。默认装完简体中文版 Windows 后,活动的 ANSI 代码页为:936(即 GBK),可用 chcp 控制台程序查看活动代码页。
NULL:取回当前 locale,不改变当前 locale。
setlocale()的作用和使用例子
当向终端、控制台输出 wchar_t 类型的字符时,需要设置 setlocale(),因为通常终端、控制台环境自身是不支持 UCS 系列的字符集编码的,使用流操作函数时(如:printf()),在标准/RT库实现的内部会将 UCS 字符转换成合适的本地 ANSI 编码字符,转换的依据就是 setlocale() 设定的活动 locale,最后将结果字符序列传递给终端,对于来自终端的输入流这个过程刚好相反。
可以用重定向输出流到文件的方法验证上面的机制:无论是 Windows CRT、Linux glibc、Cygwin glibc,使用 wprintf() 打印 wchar_t 字符文本时,重定向到文件的内容总是 GBK、UTF-8 等本地 ANSI 编码,而不会是 UCS 编码。
使用 setlocale() 的示例:
#ifdef __GNUC__ #define CSET_GBK "GBK" #define CSET_UTF8 "UTF-8" #define LC_NAME_zh_CN "zh_CN" // ifdef __GNUC__ #elif defined(_MSC_VER) #define CSET_GBK "936" #define CSET_UTF8 "65001" #define LC_NAME_zh_CN "Chinese_People's Republic of China" // ifdef _MSC_VER #endif #define LC_NAME_zh_CN_GBK LC_NAME_zh_CN "." CSET_GBK #define LC_NAME_zh_CN_UTF8 LC_NAME_zh_CN "." CSET_UTF8 #define LC_NAME_zh_CN_DEFAULT LC_NAME_zh_CN_GBK void print_current_loc(); int main(int argc, char* argv[]) { char* locname = NULL; const wchar_t* strzh = L"中文字符串"; print_current_loc(); // 使用指定的 locale locname = setlocale(LC_ALL, LC_NAME_zh_CN_DEFAULT); if ( NULL == locname ) { printf("setlocale() with %s failed.\n", LC_NAME_zh_CN_DEFAULT); } else { printf("setlocale() with %s succeed.\n", LC_NAME_zh_CN_DEFAULT); } print_current_loc(); wprintf(L"Zhong text is: %ls\n", strzh); // 使用运行环境中的 locale 设置 locname = setlocale(LC_ALL, ""); if ( NULL == locname ) { printf("setlocale() from environment failed.\n"); } else { printf("setlocale() from environment succeed.\n"); } print_current_loc(); wprintf(L"Zhong text is: %ls\n", strzh); puts("End of program."); return 0; } // 打印当前 locale void print_current_loc() { char* locname = setlocale(LC_ALL, NULL); printf("Current locale is: %s\n", locname); }
要使上面程序成功编译并执行,需要注意一下几点:
Windows CRT 是不支持 UTF-8 编码作为 locale 的,运行时使用 setlocale(LC_ALL, ".65001") 会失败。
使用 Linux 和 Cygwin 的 glibc 时,要在终端显示正确的中文,需满足以下条件:
不要混用 char 和 wchar_t 版本的流操作函数,否则会导致这些函数运行异常,我用Cygwin GCC 4测试混用 printf() 和 wprintf() 时,程序甚至崩掉,所以要将上面程序中 printf() 语句全注释掉才行。Window CRT 的实现则没有这个问题。
运行环境的 locale 设置要和程序中 setlocale() 设定的 locale 一致,比如:终端的活动字符集、环境变量(一般用 LANG),要设置为 *.UTF-8,才能显示 setlocale(LC_ALL, "zh_CN.UTF-8") 设定的 wchar_t 的中文字符。
用 GCC 编译时,要使用 UTF-8 编码保存源文件,这是 GCC 在编译时,将 wchar_t 文字量(以 L 打头)正确转换为 UCS 编码保存在对象文件中的必需条件,用 Native ANSI 编码(比如:GBK)有 wchar_t 文字量的源文件时,GCC 会编译出错,Linux 和 Cygwin 的 GCC 都有这个约束。另外在 Linux GCC 使用 UCS-4 编码保存 wchar_t,而 Windows 和 Cygwin GCC 使用 UCS-2。
用 wprintf() 时,要用 %ls 表示 wchar_t 的字符串,用 %s 表示 char 的字符串,具体参考:man 3 wprintf,而 Windows 的实现用 %ls、%s 都可以正确输出 wchar_t 字符串。
相关推荐
C语言标准函数库详解 C语言标准函数库是C语言中提供的一组预定义的函数,用于实现各种常见的操作...C语言标准函数库提供了一组强大且灵活的函数库,用于实现各种常见的操作,掌握这些函数库的使用是C语言编程的基础。
掌握这些库的使用方法对于开发高质量的C程序至关重要。通过使用这些标准库,开发者可以避免重复造轮子,提高编码效率,并确保程序的稳定性和兼容性。希望本文能帮助读者更好地理解和运用C语言标准库中的各种工具。
这里要注意两个函数的使用,用来获取当前的日期来知道星期几 1. 第一个setlocale(LC_TIME,"chs");setlocales:本地化环境;LC_TIME:用来设置本地环境的日期形式;"chs":简体中文; 2. 第二个函数也是变量:$...
了解和熟练使用C标准库的各个组件是每个C语言程序员的基本技能。 C标准库的内容非常广泛,包括但不限于输入输出处理、数学计算、字符串处理、时间日期管理、内存管理以及对底层数据表示的支持等。例如,标准输入...
C标准库是C语言程序开发中不可或缺的一部分,它为程序员提供了丰富的功能,使得编程更加方便、高效。C标准库包含了各种各样的预定义函数,这些函数涵盖了从基本的输入输出、字符串处理、数学计算,到复杂的数据结构...
#### 第一章:C标准库概览 本章节将详细介绍C语言标准库中的各个部分,包括但不限于诊断、字符类别测试、错误处理等方面的基础知识及其应用场景。 ### 1. `<assert.h>`:诊断 - **定义**:`<assert.h>` 文件仅...
C语言函数库是C标准库的重要组成部分,它是为C语言程序员提供的各种...熟练掌握这些函数库的使用方法是每个C语言程序员的基本技能。在实际应用中,理解每个函数的具体用途、参数和返回值对于编写高质量的代码至关重要。
通过以上内容的学习,我们可以了解到C语言标准库中的几个关键组成部分,以及如何使用这些组件来实现更高级别的功能,比如错误处理、字符类别检测等。这对于理解和编写高质量的C程序是非常重要的。
开发者通过`#include`指令引入所需的头文件,以便使用C标准库和自定义函数。MQTT库则为物联网应用提供了便利,使C语言程序能够轻松实现设备间的通信。不过,这个压缩包可能不包括一些特定的功能,如多字节和本地化...
《C语言函数库大全》是C语言编程者的重要参考资料,它详尽地列出了C语言标准库中的各类函数,帮助开发者理解和使用这些功能强大的工具。C语言标准库是C编程的基础,也是高效编程的关键,因此深入理解并熟练运用其中...
MSC++ 标准库参考STL C++ 标准库是指由 C++ 编程语言提供的标准库,用于帮助开发者编写高效、可靠、可维护的程序。标准库提供了大量的函数、类和模板,涵盖了字符串处理、容器、算法、输入/输出、 Localization、...
这些函数的使用方法和它们的参数类型都非常标准化,它们的实现经过了高度优化,且许多编译器的运行时库已经包含了它们的高效实现。在进行C语言编程时,合理利用这些函数可以简化开发过程,减少错误,并提高代码的可...
#### 第一章:C标准库概览 本章节将详细介绍C语言中的标准库函数,这是所有C程序员都应该了解的核心部分。这些库提供了丰富的功能,覆盖了从基本的数据类型操作到复杂的数学计算等多个领域。 ##### 1. `<assert.h>...
- C语言标准库提供了`wchar_t`类型来处理宽字符,它通常用于存储多字节字符,如Unicode字符。 - `wprintf`和`wscanf`等函数是宽字符版本的输入输出函数,可以用来处理宽字符。 3. 文件包含和头文件: - `#...
标准C标准库函数是C语言编程的重要组成部分,它提供了一系列预定义的函数,以方便程序员进行输入/输出、内存分配、数学计算等常见的操作。本文将基于C99标准库,结合网络资源和自编测试用例,对C语言标准库中的各种...
1. **标准C库** (glibc):这是最基础的库,包含了C语言的基本函数,如内存管理(malloc, free)、输入/输出(printf, scanf)和字符串处理(strcpy, strcat)。它还提供了系统调用的接口,如open, read, write等,...
- 对于复杂的国际化需求,可能还需要考虑使用更高级的库或框架来处理多语言支持。 综上所述,`setlocal` 函数为 C/C++ 开发者提供了一个强大的工具,可以轻松地为程序添加本地化支持,从而使得程序能够在各种语言和...