C++学习------clocale头文件的源码学习01

152 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情

引言

clocale是C++对locale.h头文件的封装,该文件是本地化的特殊设置,比如特殊的时间日期打印格式,货币符号等。我们来看看它的具体实现。

locale.h

参考代码: www.aospxref.com/android-12.…

locale.h中设置的影响

上面说到,locale.h实际上是与本地化相关的设置,所以使用这个头文件,会对其它标准C函数有一些影响:

  • string.h里面的strcoll和strxfrm会被符号转换规则影响;
  • ctypes.h里面除了isdigit和isxdigit其余的函数都会被该文化特有的扩展符号影响;
  • stdio.h里面的输入输出过程中会被符号转换规则和特殊设定的小数点符号影响;
  • time.h里面的strftime会被时间格式设置影响。

宏定义

按照local的相关类型,如时间,金钱符号等,设置了宏定义及对应的mask,以便后续使用。

40  #define LC_CTYPE           0
41  #define LC_NUMERIC         1
42  #define LC_TIME            2
43  #define LC_COLLATE         3
44  #define LC_MONETARY        4
45  #define LC_MESSAGES        5
46  #define LC_ALL             6
47  #define LC_PAPER           7
48  #define LC_NAME            8
49  #define LC_ADDRESS         9
50  #define LC_TELEPHONE      10
51  #define LC_MEASUREMENT    11
52  #define LC_IDENTIFICATION 12
53  
54  #define LC_CTYPE_MASK          (1 << LC_CTYPE)
55  #define LC_NUMERIC_MASK        (1 << LC_NUMERIC)
56  #define LC_TIME_MASK           (1 << LC_TIME)
57  #define LC_COLLATE_MASK        (1 << LC_COLLATE)
58  #define LC_MONETARY_MASK       (1 << LC_MONETARY)
59  #define LC_MESSAGES_MASK       (1 << LC_MESSAGES)
60  #define LC_PAPER_MASK          (1 << LC_PAPER)
61  #define LC_NAME_MASK           (1 << LC_NAME)
62  #define LC_ADDRESS_MASK        (1 << LC_ADDRESS)
63  #define LC_TELEPHONE_MASK      (1 << LC_TELEPHONE)
64  #define LC_MEASUREMENT_MASK    (1 << LC_MEASUREMENT)
65  #define LC_IDENTIFICATION_MASK (1 << LC_IDENTIFICATION)
66  
67  #define LC_ALL_MASK (LC_CTYPE_MASK | LC_NUMERIC_MASK | LC_TIME_MASK | LC_COLLATE_MASK | \
68                       LC_MONETARY_MASK | LC_MESSAGES_MASK | LC_PAPER_MASK | LC_NAME_MASK | \
69                       LC_ADDRESS_MASK | LC_TELEPHONE_MASK | LC_MEASUREMENT_MASK | \
70                       LC_IDENTIFICATION_MASK)

类型定义---lconv

该类型定义,包含了所有特殊设置项:

  • decimal_point---用于非货币量的小数点分隔符;
  • thousands_sep---用于分隔非货币量小数点左侧的数字组的分隔符;
  • grouping---指定形成每个组的位数,对于非货币量,这些数字将由千分位分隔符分隔。 举个例子,比如thousand_sep = ',',当我们表示1000000时: grouping = '\3',那就表示为'1,000,000'; grouping = '\1\2\3',那就表示为'1,000,00,0'; grouping = '\3\1',那就表示为'1,0,0,0,000'。
  • int_curr_symbol---国际货币符号;
  • currency_symbol---本地货币符号,如“$”;
  • mon_decimal_point---用于货币量的小数点分隔符;
  • mon_thousands_sep---分隔符,用于分隔货币量小数点左侧的数字组;
  • mon_grouping---指定形成每个组的数字数量,这些数字由货币量的mmon_thousands_sep分隔符分隔;
  • positive_sign---用于非负(正或零)货币量的符号;
  • negative_sign---用于负货币量的符号;
  • int_frac_digits---国际格式货币量小数点右侧的小数位数
  • frac_digits---本地格式货币量小数点右侧的小数位数
  • p_cs_precedes---货币符号是否应在非负(正或零)货币量之前。如果该值为1,则货币符号应在前;如果为0,则应跟随;
  • p_sep_by_space---货币符号和非负(正或零)货币量之间是否应出现空格。如果该值为1,则应显示一个空格;如果为0,则无空格;
  • n_cs_precedes---货币符号是否应在负货币量之前。如果该值为1,则货币符号应在前;如果为0,则应跟随;
  • n_sep_by_space---货币符号和负货币量之间是否应出现空格。如果该值为1,则应显示一个空格;如果为0,则无空格;
  • p_sign_posn---非负(正或零)货币量的符号位置:
    • 0:用括号括起来的货币符号和数量;
    • 1:在数量和货币符号前签名;
    • 2:在数量和货币符号后签名;
    • 3:在货币符号前签名;
    • 4:在货币符号后面签名。
  • n_sign_posn---负货币量符号的位置;
  • int_p_cs_precedes---同p_cs_precedes,国际格式;
  • int_p_sep_by_space---同p_sep_by_space,国际格式;
  • int_n_cs_precedes---同n_cs_precedes,国际格式;
  • int_n_sep_by_space---同n_sep_by_space,国际格式;
  • int_p_sign_posn---同p_sign_posn,国际格式;
  • int_n_sign_posn---同n_sign_posn,国际格式;
72  struct lconv {
73    char* decimal_point;
74    char* thousands_sep;
75    char* grouping;
76    char* int_curr_symbol;
77    char* currency_symbol;
78    char* mon_decimal_point;
79    char* mon_thousands_sep;
80    char* mon_grouping;
81    char* positive_sign;
82    char* negative_sign;
83    char int_frac_digits;
84    char frac_digits;
85    char p_cs_precedes;
86    char p_sep_by_space;
87    char n_cs_precedes;
88    char n_sep_by_space;
89    char p_sign_posn;
90    char n_sign_posn;
91    char int_p_cs_precedes;
92    char int_p_sep_by_space;
93    char int_n_cs_precedes;
94    char int_n_sep_by_space;
95    char int_p_sign_posn;
96    char int_n_sign_posn;
97  };

函数定义参看下一节