The locale of a process determines the way character collation, character classification, date and time formatting, numeric punctuation, monetary punctuation, and message output are handled. The following section describes how to set and access information about the current locale in a program using National Language Support (NLS).
Every internationalized program must set the current locale using the setlocale subroutine. This subroutine allows a process to change or query the current locale by accessing locale databases.
When a process is started, its current locale is set to the C or POSIX locale. A program that depends on locale data not defined in the C or POSIX locale must invoke the setlocale subroutine in the following manner before using any of the locale-specific information:
setlocale(LC_ALL, "");
The following subroutines provide access to information defined in the current locale as determined by the most recent call to the setlocale subroutine:
localeconv | Provides access to locale information defined in the LC_MONETARY and LC_NUMERIC categories of the current locale. The localeconv subroutine retrieves information about these categories, places the information in a structure of type lconv as defined in the locale.h file, and returns a pointer to this structure. |
nl_langinfo | Returns a pointer to a null-terminated string containing information defined in the LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, and LC_TIME categories of the current locale. |
rpmatch | Tests for positive and negative responses. These are specified in the LC_MESSAGES category of the current locale. Responses can be regular expressions as well as simple strings. The rpmatch subroutine is not an industry-standard subroutine. Portable applications should not assume that this subroutine is available. |
The localeconv and nl_langinfo subroutines do not provide access to all LC_* categories.
The current locale setting for a category can be obtained by: setlocale( Category, ( char *) 0 ) . The return value is a string specifying the current locale for Category. The following example determines the current locale setting for the LC_CTYPE category:
char *ctype_locale; ctype_locale = setlocale(LC_CTYPE, (char*)0);
#include <locale.h> main() { char *p; p = setlocale(LC_ALL, ""); /* ** The program will have the locale as set by the ** LC_* and LANG variables. */ }
#include <stdio.h> #include <locale.h> main() { char *p; /* set the current locale to what is specified */ p = setlocale(LC_ALL, ""); /* The current locale settings for all the ** categories is pointed to by p */ /* ** Find the current setting for the ** LC_COLLATE category */ p = setlocale(LC_COLLATE, NULL); /* ** p points to a string containing the current locale ** setting for the LC_COLLATE category. */ }
#include <stdio.h> #include <locale.h> #include <string.h> #define NEW_LOCALE "MY_LOCALE" main() { char *p, *save_locale; p = setlocale(LC_ALL, ""); /* ** Initiate locale. p points to the current locale ** setting for all the categories */ save_locale = (char *)malloc(strlen(p) +1); strcpy(save_locale, p); /* Save the current locale setting */ p = setlocale(LC_ALL, NEW_LOCALE); /* Change to new locale */ /* ** Do processing ... */ /* Change back to old locale */ p = setlocale(LC_ALL, save_locale); /* Restore old locale */ free(save_locale); /* Free the memory */ }
#include <locale.h> main() { char *p; /* ** The program starts in the C locale for all categories. */ p = setlocale(LC_MESSAGES, ""); /* ** At this time the LC_COLLATE, LC_CTYPE, LC_NUMERIC, ** LC_MONETARY, LC_TIME will be in the C locale. ** LC_MESSAGES will be set to the current locale setting ** as determined by the environment variables. */ }
#include <locale.h> main() { struct lconv *ptr; char *decimal; (void)setlocale(LC_ALL, ""); ptr = localeconv(); /* ** Access the data obtained. For example, ** obtain the current decimal point setting. */ decimal = ptr->decimal_point; }
#include <langinfo.h> #include <locale.h> main() { char *ptr; (void)setlocale(LC_ALL, ""); ptr = nl_langinfo(D_T_FMT); }
#include <langinfo.h> #include <locale.h> main() { char *ptr; (void)setlocale(LC_ALL, ""); /* Set the program's locale */ ptr = nl_langinfo(RADIXCHAR); /* Obtain the radix character*/ }
#include <langinfo.h> #include <locale.h> main() { char *ptr; (void)setlocale(LC_ALL, ""); /* Set the program's locale */ ptr = nl_langinfo(CRNCYSTR); /* Obtain the currency string*/ /* The currency string will be "-$" in the U. S. locale. */ }
The affirmative and negative responses as specified in the locale database are no longer simple strings; they can be regular expressions. For example, the yesexpr can be the following regular expression, which will accept an upper or lower case letter y , followed by zero or more alphabetic characters; or the character O followed by K . Thus, yesexpr may be the following regular expression:
([yY][:alpha:]*|OK)
The standards do not contain a subroutine to retrieve and compare this information. You can use the AIX-specific rpmatch(const char *response) subroutine.
#include <stdio.h> #include <langinfo.h> #include <locale.h> #include <regex.h> int rpmatch(const char *); /* ** Returns 1 if yes response, 0 if no response, ** -1 otherwise */ main() { int ret; char *resp; (void)setlocale(LC_ALL, ""); do { /* ** Obtain the response to the query for yes/no strings. ** The string pointer resp points to this response. ** Check if the string is yes. */ ret = rpmatch(resp); if(ret == 1){ /* Response was yes. */ /* Process accordingly. */ }else if(ret == 0){ /* Response was negative. */ /* Process negative response. */ }else if(ret<0){ /* No match with yes/no occurred. */ continue; } }while(ret <0); }
Note that nl_langinfo(YESEXPR) and nl_langinfo(NOEXPR) are used to obtain the regular expressions for the affirmative and negative responses respectively.
#include <langinfo.h> #include <regex.h> /* ** rpmatch() performs comparison of a string to a regular expression ** using the POSIX.2 defined regular expression compile and match ** functions. The first argument is the response from the user and the ** second string is the current locale setting of the regular expression. */ int rpmatch( const char *string) { int status; int retval; regex_t re; char *pattern; pattern = nl_langinfo(YESEXPR); /* Compile the regular expression pointed to by pattern. */ if( ( status = regcomp( &re, pattern, REG_EXTENDED | REG_NOSUB )) != 0 ){ retval = -2; /*-2 indicates yes expr compile error */ return(retval); } /* Match the string with the compiled regular expression. */ status = regexec( &re, string, (size_t)0, (regmatch_t *)NULL, 0); if(status == 0){ retval = 1; /* Yes match found */ }else{ /* Check for negative response */ pattern = nl_langinfo(NOEXPR); if( ( status = regcomp( &re, pattern, REG_EXTENDED | REG_NOSUB )) != 0 ){ retval = -3;/*-3 indicates no compile error */ return(retval); } status = regexec( &re, string, (size_t)0, (regmatch_t *)NULL, 0); if(status == 0) retval = 0;/* Negative response match found */ }else retval = -1; /* The string did not match yes or no response */ regfree(&re); return(retval); }
National Language Support Subroutines Overview provides information about wide character and multibyte subroutines.
For general information about internationalizing programs, see National Language Support Overview for Programming and Locale Overview for Programming.
For more information about using locales, see Locale Overview for System Management in AIX Version 4.3 System Management Guide: Operating System and Devices.
Character Set Description (charmap) source file format, Locale Definition source file format.
For specific information about locale categories and their keywords, see the LC_COLLATE category, LC_CTYPE category, LC_MESSAGES category, LC_MONETARY category, LC_NUMERIC category, and LC_TIME category.