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

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

    22个wordpress常见问题集合

    22个常见的wordpress问题集合,所有的wordpress问题全部解答,没有解答不了的问题,只要不认真看的。

    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

Global site tag (gtag.js) - Google Analytics