`
huobengle
  • 浏览: 862479 次
文章分类
社区版块
存档分类
最新评论

C标准库的setlocale()用法笔记

 
阅读更多

C 和 C++ 的标准库分别有自己的 locale 操作方法,C 标准库的 locale 设定函数是 setlocale(),而 C++ 标准库有 locale 类和流对象的 imbue() 方法。这篇是我自己的 setlocale() 使用总结。

Linux的glibc中的setlocale()

具体参考:man 3 setlocale

头文件与声明如下:


说明

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 被初始化为默认的Clocale,其采用的字符编码是所有本地 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):

  1. lang[_country_region[.code_page]]:虽然形式与 glibc 的相同,当 Windows 的 locale 名并不符合 POSIX 的规范,比如采用 GBK 字符集的大陆中文,POSIX 的名字为:zh_CN.GBK,而在 Windows CRT 中要用:Chinese_People's Republic of China.936,(-_-^)。

  2. .code_page:可以直接使用代码页来设定 locale,而且可以使用 .OCP、.ACP 两个伪代码页,.OCP 表示从系统获得的当前活动的 OEM 代码页,.ACP 表示从系统获得的活动 ANSI 代码页。

  3. "":根据 Windows 系统环境的活动 ANSI 代码页来设定 locale。.OCP、.ACP、和环境代码页都受控制面板中“区域与语言选项”的设置影响。默认装完简体中文版 Windows 后,活动的 ANSI 代码页为:936(即 GBK),可用 chcp 控制台程序查看活动代码页。

  4. 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() 的示例:



要使上面程序成功编译并执行,需要注意一下几点:

Windows CRT 是不支持 UTF-8 编码作为 locale 的,运行时使用 setlocale(LC_ALL, ".65001") 会失败。

使用 Linux 和 Cygwin 的 glibc 时,要在终端显示正确的中文,需满足以下条件:

  1. 不要混用 char 和 wchar_t 版本的流操作函数,否则会导致这些函数运行异常,我用Cygwin GCC 4测试混用 printf() 和 wprintf() 时,程序甚至崩掉,所以要将上面程序中 printf() 语句全注释掉才行。Window CRT 的实现则没有这个问题。

  2. 运行环境的 locale 设置要和程序中 setlocale() 设定的 locale 一致,比如:终端的活动字符集、环境变量(一般用 LANG),要设置为 *.UTF-8,才能显示 setlocale(LC_ALL, "zh_CN.UTF-8") 设定的 wchar_t 的中文字符。

  3. 用 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。

  4. 用 wprintf() 时,要用%ls表示 wchar_t 的字符串,用%s表示 char 的字符串,具体参考:man 3 wprintf,而 Windows 的实现用 %ls、%s 都可以正确输出 wchar_t 字符串。

    这里有一篇 Love Katherine 的:浅谈C中的wprintf和宽字符显示,对 Linux 使用 wchar_t 分析的挺好,做下收藏。

分享到:
评论

相关推荐

    VBS中的SetLocale函数到底有什么用?

    写了这么多VBS,从来都没有使用过SetLocale函数,似乎也没有见过谁的代码使用过,这个SetLocale函数到底有什么用呢

    SetLocale:用于设置设备区域设置的简单应用程序

    设置区域 用于设置设备区域设置的简单应用程序。 注意:在 Android 4.2 及更高版本上,您必须手动授予应用所需的权限: ...下午授予 com.darkrockstudios.apps.setlocale android.permission.CHANGE_CONFIGURATION

    C标准库函数.CHM

    The C Library Reference Guide by Eric Huss © Copyright 1997 Eric Huss Introduction 1. Language 1.1 Characters 1.1.1 Trigraph Characters 1.1.2 Escape Sequences 1.1.3 Comments 1.2 Identifiers ...

    switch.php

    这里要注意两个函数的使用,用来获取当前的日期来知道星期几 1. 第一个setlocale(LC_TIME,"chs");setlocales:本地化环境;LC_TIME:用来设置本地环境的日期形式;"chs":简体中文; 2. 第二个函数也是变量:$...

    js 实现 在JavaScript运行VBScript函数

    js 实现 在JavaScript运行VBScript函数! 值得下载看看!资源免费,大家分享!!

    fmt标签 fmt标签 fmt 标签

    fmt标签 fmt标签 fmt 标签 fmt标签 fmt标签 fmt 标签 fmt标签 fmt标签 fmt 标签

    unity xlua lua5.4.6最新版lua库文件

    - 修复了 setlocale 函数在某些情况下崩溃的漏洞 - 修复了 load 函数在解析代码期间返回意外的错误类型的漏洞 - 修改了 require 函数的行为,现在它在找不到模块时不会调用 C 中的 findloader 函数 - 提高了内存...

    详解PHP使用日期时间处理器Carbon人性化显示时间

    Carbon 日期时间处理库可以很方便的处理时间,github地址为...使用方法也很简单 <?php require 'vendor/autoload.php'; use Carbon\Carbon; //显示中文 Carbon::setLocale('zh'); //获取昨天的时间戳 $ts = Carb

    libxl4.1.1完美版

    windows版本和linux版本libxl库均能够完美使用。

    使用Java国际化和本地化实现一个简单的多语言应用.txt

    这个代码实现了一个简单的多语言应用。首先,我们定义了三种...在setLocale()方法中,我们更新当前的语言设置。这个例子展示了如何使用Java的国际化和本地化功能来实现多语言应用,可以提高程序的可移植性和用户体验。

    Test_Program:演示程序,学习笔记,最佳实践

    此文件夹包含许多小型测试程序。 我的StackOverflow解决方案: setlocale.c chrono.cpp bash_read_line / do.sh express-curl-xml / flask_classy_demo / sinon_doh_demo / 材料: 向量 fifo队列

    shm.rar_android

    Remove tests setlocale() to other than , C , and POSIX for Android.

    翻译和本地化库Counterpart.zip

    Counterpart 是一个翻译和本地化库,用于 Node.js 和浏览器。示例代码:translate.registerTranslations('de', require('counterpart/locales/de')); translate.registerTranslations('de', require('./locales/de...

    jquery时间选取插件datetimepicker,示例“2018/05/10 16:20”(中文版)

    jquery时间选取插件datetimepicker,示例格式为“2018/05/10 16:20”。需定制修改样式需要自行百度查找。关键词jquery.datetimepicker。

    VBSCRIP5 -ASP用法详解

    SetLocale 函数 设置全局区域设置,返回以前区域设置. Sgn 函数 返回表示数的符号的整数。 Sin 函数 返回角度的正弦值。 Source 属性 返回最早出错的对象或应用程序的名称。 Space 函数 返回由指定数量的空格...

    -C++参考大全(第四版) (2010 年度畅销榜

    第四部分讨论了标准类库,包括STL(标准模板库);第五部分显示了两个应用C++和面向对象编程的实际例子。 本书内容全面、翔实,是学习C++编程语言的广大学生的一部有用的工具书,也是对C++感兴趣的读者的必备参考书。 ...

    PHP中localeconv()函数的用法

    定义和用法 localeconv()函数返回一个包含本地数字及货币格式信息的数组。 localeconv()函数返回以下数组元素: [decimal_point] – 小数点字符 [thousands_sep] – 千位分隔符 [int_curr_symbol] – 货币符号 ...

    pdf电子准考证查询下载系统(实证效果可照片)V1.0

    windows:代码第二行前插入一行:setlocale(LC_ALL, 'C'); 本系统核心pdf处理代码基于fpdf,(MIT license)。 优于pdf证书仅部分电脑端浏览器支持预览,故仅查询和下载。 自带数据和图片仅供演示,请勿将本系统用于...

    CMD以及VBS的所有命令帮助

    有CMD的所有函数命令帮助:ASSOC AT ATTRIB BREAK CACLS CALL CD CHCP CHDIR CHKDSK CHKNTFS CLS CMD COLOR COMP COMPACT CONVERT COPY DATE DEL DIR DISKCOMP ...CByte ...CInt ...SetLocale TypeName VarType

    验证不同ISO和ZIP编码的PHP库.zip

    iso,国际标准光盘文件系统格式。符合ISO 9660标准的光盘镜像文件格式,文件扩展名通常为iso。这种文件可以简单的理解为复制光盘上全部信息而形成的镜像文件。ZIP,是一个文件的压缩的算法,原名Deflate(真空),...

Global site tag (gtag.js) - Google Analytics