Ste*_*eve 13 c linux environment-variables
我已经读过每个进程都有一组与之关联的语言环境变量.例如,这些是与bash我系统上的进程关联的语言环境变量:
$ locale
LANG="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_CTYPE="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_ALL=
Run Code Online (Sandbox Code Playgroud)
我想知道谁实际使用这些语言环境变量.
C标准函数(例如:) fwrite()和Linux系统调用是否使用它们?某些C标准函数或某些Linux系统调用的行为是否因某些语言环境变量的值而异?
或者只是某些程序可以使用这些区域设置变量?例如,我可以编写一个程序,根据LANGlocale变量的值,以不同的语言向用户显示消息.
Max*_*kin 11
默认情况下,C的标准库函数使用"C"语言环境.您可以将其切换到用户区域设置以启用特定于区域设置:
POSIX setlocale文档包含受其影响的区域设置相关函数的不完整列表:
catopen,exec,fprintf,fscanf,isalnum,isalpha,isblank,iscntrl,isdigit,isgraph,islower,isprint,ispunct,isspace,isupper,iswalnum,iswalpha,iswblank,iswcntrl,iswctype,iswdigit,iswgraph,iswlower,iswprint,iswpunct, iswspace,iswupper,iswxdigit,isxdigit,localeconv,mblen,mbstowcs,mbtowc,newlocale,nl_langinfo,perror,psiginfo,setlocale,strcoll,strerror,strfmon,strftime,strsignal,strtod,strxfrm,tolower,toupper,towlower,towupper,uselocale, wcscoll,wcstod,wcstombs,wcsxfrm,wctomb
例如:
printf("%'d\n", 1000000000);
printf("Setting LC_ALL to %s\n", getenv("LANG"));
setlocale(LC_ALL, ""); // Set user-preferred locale.
printf("%'d\n", 1000000000);
Run Code Online (Sandbox Code Playgroud)
输出:
1000000000
Setting LC_ALL to en_US.UTF-8
1,000,000,000
Run Code Online (Sandbox Code Playgroud)
我已经读到每个进程都有一组与之关联的语言环境变量。
这不是真的,或者至少是过度简化了。
许多标准库函数(和非标准库函数)基于一组语言环境配置来修改其行为,这些语言环境配置在标准库实现中的某些隐藏全局对象中维护。(在某些库实现中,使用线程局部静态变量按线程而不是全局维护语言环境配置。)这似乎与进程相关联,因为通常每个进程都具有标准库运行时的单个实例,但重要的是要理解,尽管有出现,但语言环境支持是库的一部分,而不是OS内核。(当然,任何标准都没有定义内核边界的位置,甚至可能定义内核的边界。您可以“裸机”运行程序 或者您可能拥有一个认为在系统调用中实现标准库很有用的操作系统。我在这里谈论的是常见情况。)
基本语言环境配置由C标准在C11标准的7.11节中定义,该标准定义了两个接口:
setlocale,它修改了库的语言环境配置,以及
localeconv,它查询语言环境配置的一部分,从而允许用户代码符合语言环境的数字格式约定(包括货币格式)。
语言环境配置分为多个或多或少的独立组件,称为“类别”。(C ++标准库将这些词称为“方面”,这也是一个常用的词。)C标准定义了五种类别,而Posix定义了五种类别,但是这些类别是开放式的。各个标准库的实现都可以自由添加其他类别。例如,大多数Linux系统上使用的Gnu标准C库当前共有12个类别。(有关man 7 locale最新列表,请参见系统上的。)
标准类别为:
LC_CTYPE:字符分类和大小写转换。LC_COLLATE:整理顺序。LC_MONETARY:货币格式。LC_NUMERIC:数字,非货币格式。LC_TIME:日期和时间格式。而Posix扩展名是:
LC_MESSAGES:信息和诊断消息以及交互响应的格式。 除了之外localeconv,该方法仅提供对LC_NUMERIC和LC_MONETARY类别中特定配置的访问,无法查询任何特定配置。
而且,根本没有标准方法来设置单个配置。您所能做的就是使用setlocale依赖于库的非标准语言环境名称(这只是一个字符串)来配置整个类别。更准确地说,两个语言环境名称已标准化:
C标准定义了语言环境名称C。
Posix定义语言环境名称POSIX。但是,Posix指定相应的语言环境应与名为的语言环境相同C。
语言环境命名的详细信息在(或应该在)locale您正在使用的环境的文档中进行了详细说明,但是通常,支持语言环境的程序绝不会setlocale使用标准名称或空字符串以外的字符串常量进行调用。(我等会儿。)
该setlocale界面允许程序设置单个区域设置类别,或将所有区域设置类别设置为相同的区域设置名称。它还返回一个字符串,该字符串可用于返回到先前配置的语言环境类别(或完整的配置)。
上面的类别列表中显示的类别名称是在中定义的宏<locale.h>。LC_ALL该头文件还定义了一个附加宏:LC_ALL。这些宏之一必须用作的第一个参数setlocale。
C和Posix标准都要求程序启动时的初始语言环境设置是C语言环境。C语言环境的许多方面都是标准化的(而语言环境的更多方面Posix是标准化的)。例如,这种标准化可使程序员预测数字转换的工作方式。
但是通常情况下,程序员会希望使用该用户自己的区域设置首选项与该程序的用户进行交互。显然不希望每个程序都有自己的特殊机制来确定用户的语言环境首选项,因此标准库提供了一种机制,用于将语言环境(或各个语言环境类别)设置为默认语言环境配置为:setlocale使用空字符串("")作为语言环境名称。C标准没有指定用于配置此信息的任何特定机制;它仅假设一个存在。
(旁注:setlocale以空字符串作为语言环境名称进行调用与以语言环境名称进行调用是不同的。告诉您不要更改任何语言环境设置,但仍会返回与当前语言环境关联的字符串。这避免了使用接口。)setlocaleNULLNULLsetlocalegetlocale
Posix确实指定了一种配置用户首选项的机制,并且还坚持要求(大多数)标准化的命令行实用程序在默认语言环境中运行。该机制使用名称与setlocale类别宏相对应的环境变量。
在Posix实现上,当程序调用时setlocale(LC_X, "");,库将继续检查当前环境:
首先,它查找环境变量LC_ALL。如果已定义并且具有非空值,则用于定义语言环境。
否则,如果第一个参数setlocale是不是LC_ALL看起来的环境变量,它的名称是相同的说法。如果已定义并且具有非空值,则用于定义语言环境。
否则,如果环境变量LANG已定义且具有非空值,则将其(以某种实现相关的方式)用于构造语言环境名称。(LANG应该指出用户的语言,这是他们的语言环境首选项的重要组成部分。)
最后,使用一些系统范围的默认值。
环境变量通常由login程序(或GUI等效项)根据系统配置文件进行初始化。(精确的机制因发行而异,通常很难找到文档。)
如前所述,Posix几乎需要所有标准的shell实用程序才能执行等效的setlocale(LC_ALL, "");操作,以便在用户配置的语言环境中进行操作。每个实用程序的手册页(或其他文档)都应指定是否执行此操作,但是除非有相反的信息,否则可以合理地假定它可以执行此操作。
同样,许多(但不是全部)标准库字符串函数都支持区域设置。绝对不支持区域设置的库接口包括isdigit和isxdigit,它们始终根据C区域设置进行响应,而和则以strcmp与相同的方式比较字符串memcmp,使用char值(解释为unsigned int)确定排序顺序。(strcoll如果您要根据进行比较,则是区域设置感知的LC_COLLATE。)并且,用于宽和多字节字符的字符编码由LC_CTYPE类别控制(以某种未指定的方式)。
| 归档时间: |
|
| 查看次数: |
448 次 |
| 最近记录: |