C语言标准库函数setlocale用法详解

C语言标准库函数setlocale用法详解

C语言标准库函数setlocale定义在 <locale.h> 头文件中(在C++编程中,这个头文件等价于 <clocale> )。

原型:

c 复制代码
char* setlocale (int category, const char* locale);

函数参数解析

category

int类型,可以取以下几个值:

影响范围
LC_ALL 全部更改为传入的locale
LC_COLLATE 影响字符串比较函数 strcol1()和 strxfrm()。
LC_CTYPE 影响字符处理函数的行为。
LC_MONETARY 影响货币格式
LC_NUMERIC 影响 printf() 的数字格式
LC_TIME 影响时间格式 strftime()和 wcsftime()。

locale

locale参数是字符串(char*)类型,有以下几种写法:

| "language[_country-region[.code-page]]"

  1. 名称写法,例如中文多字节代码页""
  2. Windows特有的代码页写法 ".code-page",例如936代码页的locale,".936";65001代码页的locale,".65001"。
  3. 通用选项"C"、""、NULL

常见的locale本地化参数效果如下表所示:

效果
"C" 采用仅支持ASCII的最小本地化配置
NULL 不改变任何设置,函数仅返回当前的locale名称
"" 采用当前系统环境的默认代码页。例如中文Windows系统默认的locale为ANSI/OEM 936
".utf8" 使用UTF-8本地化
".utf-8" 使用UTF-8本地化
"en_us.utf8" 使用UTF-8本地化
"LC_MONETARY=en-US;LC_TIME=ja-JP" 货币使用en-US本地化(美国货币符号),时间使用ja-JP本地化(日本时间格式)

更多设置格式,可参考文末UCRT Locale names, Languages, and Country/Region strings链接。

应用

本节给出setlocale函数的具体应用,以便读者体会其功能。

应用1:在控制台打印宽字符

为输出宽字符,调用setlocale是必要的。

看一段例程:

c 复制代码
/* setlocale example */
#include <stdio.h>      /* printf */
#include <time.h>       /* time_t, struct tm, time, localtime, strftime */
#include <locale.h>     /* struct lconv, setlocale, localeconv */

int main ()
{
    wchar_t* pstr0=L"Wide Character Test 0\n";
    wprintf(pstr0);
    wchar_t* pstr1=L"宽字符测试1\n";
    wprintf(pstr1);
    setlocale(LC_ALL,"");
    wchar_t* pstr2=L"宽字符测试2\n";
    wprintf(pstr2);
    return 0;
}

运行后得到如下输出:

Wide Character Test 0

宽字符测试2

也就是说,调用setlocale之前,程序的默认本地化环境是 "C" ,只支持 ASCII 字符,中日韩等非ASCII字符会被视为无效字符。

而wprintf函数输出字符串到控制台时,需要先将UTF-16编码的字符数据转换成多字节编码(如GBK、UTF-8等)数据。调用setlocale之前,包含了中日韩字符的字符串转换过程必失败,从而导致L"宽字符测试1"未被输出。

将setlocale的调用位置放到程序最开始,再次尝试:

c 复制代码
/* setlocale example */
#include <stdio.h>      /* printf */
#include <time.h>       /* time_t, struct tm, time, localtime, strftime */
#include <locale.h>     /* struct lconv, setlocale, localeconv */

int main ()
{
    setlocale(LC_ALL,"");
    wchar_t* pstr0=L"Wide Character Test 0\n";
    wprintf(pstr0);
    wchar_t* pstr1=L"宽字符测试1\n";
    wprintf(pstr1);
    wchar_t* pstr2=L"宽字符测试2\n";
    wprintf(pstr2);
    return 0;
}

运行后得到如下输出:

Wide Character Test 0

宽字符测试1

宽字符测试2

应用2:控制货币、时间日期格式

请运行代码以切实体会setlocale的不同参数对货币符号、时间日期格式的影响:

c 复制代码
/* setlocale example */
#include <stdio.h>      /* printf */
#include <time.h>       /* time_t, struct tm, time, localtime, strftime */
#include <locale.h>     /* struct lconv, setlocale, localeconv */

int main ()
{
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];

  struct lconv * lc;

  time ( &rawtime );
  timeinfo = localtime ( &rawtime );

  int twice=0;

  do {
    printf ("Locale is: %s\n", setlocale(LC_ALL,NULL) );

    strftime (buffer,80,"%c",timeinfo);
    printf ("Date is: %s\n",buffer);

    lc = localeconv ();
    printf ("Currency symbol is: %s\n-\n",lc->currency_symbol);

    setlocale (LC_ALL,"");
  } while (!twice++);

  return 0;

命令行输出结果为:

参考

来自cplusplus.com的setlocale函数定义与示例

微软文档:

setlocale, _wsetlocale
UCRT Locale names, Languages, and Country/Region strings

相关推荐
叫我木子4 小时前
c语言,识别到黑色就自动开枪,4399单击游戏狙击战场,源码分享,豆包ai出品
c语言·人工智能·游戏
l1t4 小时前
对expat库XML_Parse函数调用优化的测试
xml·c语言·解析器·expat
l1t5 小时前
利用美团龙猫添加xlsx的sheet.xml读取sharedStrings.xml中共享字符串输出到csv功能
xml·c语言·数据结构·人工智能·算法·解析器
l1t6 小时前
how to build tbox xml into the demo
xml·linux·c语言·parser·tbox
九皇叔叔7 小时前
【2】标识符
c语言
野生的编程萌新8 小时前
【C++深学日志】从0开始的C++生活
c语言·开发语言·c++·算法
Hello_Embed11 小时前
STM32HAL 快速入门(二十四):I2C 编程(一)—— 从 OLED 显示初识 I2C 协议
c语言·stm32·单片机·嵌入式硬件·学习
晨非辰14 小时前
#C语言——刷题攻略:牛客编程入门训练(十一):攻克 循环控制(三),轻松拿捏!
c语言·开发语言·经验分享·学习·visual studio
嫣语岁月15 小时前
【BMS电池管理】基于BQ76920与STM32的BMS设计开发
c语言·vscode·stm32·单片机·嵌入式硬件
PAK向日葵19 小时前
【C/C++】面试官:手写一个memmove,要求性能尽可能高
c语言·c++·面试