Keil Logo

ARM: How to customize a locale used by setlocale()


Information in this knowledgebase article applies to:

  • Keil MDK
  • Arm Compiler 5, and newer versions

QUESTION

The language shown in our target product's touchscreen can be changed from English to German. 

I want to change the format of numeric characters from English to German accordingly as well, such as showing the number 3,14 in the German format, instead of 3.14 in the English format.

I have tried using setlocale() as follows to change the LC_NUMERIC category to de_DE. But the numeric result is still 3.14 in the English format. 

How can I change the locale to German using setlocale()?

#include "locale.h"

float f = 3.14;
char test[20];
if (setlocale(LC_NUMERIC, "de_DE") == NULL){
   printf ("setlocale failed!\n");
}
sprintf(test, "Number: %.2f\n", f);
printf ("%s\n", test);

ANSWER

As written in the Arm C and C++ Library Functions Reference manual, as the second argument of setlocale(), the valid locale values depend on which __use_X_ctype symbol is imported (__use_iso8859_ctype, __use_sjis_ctype, or __use_utf8_ctype), and on user-defined locales.

Because in the Arm C and C++ Library, there is no such a locale de_DE defined in any of symbol sets listed above, the locale value de_DE cannot be used directly for setlocale(). 

A user-defined locale called de_DE has to be customized as follows.

  1. Disable Use MicroLIB under Options for Target - Target in µVision
  2. Add a new de_locale.s assembler file to your project with the following assembler code
       AREA my_locales, DATA, READONLY
       GET rt_locale.s
    my_numeric_locales
       LC_NUMERIC_begin de_numeric, "de_DE"
       LC_NUMERIC_point ","
       LC_NUMERIC_thousands ""
       LC_NUMERIC_grouping ""
       LC_NUMERIC_end
       LC_index_end
       AREA my_locale_func, CODE, READONLY
       EXPORT _get_lc_numeric
       IMPORT _findlocale
    _get_lc_numeric FUNCTION
       LDR r0, =my_numeric_locales
       B _findlocale
       ENDFUNC
       END
    
    The macros used above, such as LC_NUMERIC_begin, LC_NUMERIC_point etc., are defined in the rt_locale.s file located in your Arm Compiler toolchain installation folder.
  3. Add the path to the rt_locale.s file, such as "C:\Keil\ARM\ARMCC\include\", to Options for Target - Asm - Include Paths in µVision.
  4. For testing your customized locale de_DE, you can write the following C code in one of your C source file.
    #include "locale.h"
    
    float f = 3.14;
    char test[20];
    char * current_locale;
    // Set your own numeric locale "de_DE".
    current_locale = setlocale(LC_NUMERIC, "de_DE");
    if(current_locale != NULL)
    {
       printf("current Numeric locale is : %s \n", current_locale);
    }
    sprintf(test, "Number: %.2f\n", f);
    printf ("%s\n", test);
    

MORE INFORMATION

SEE ALSO

Last Reviewed: Friday, October 30, 2020


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.