Chapter Contents

Previous

Next
localeconv

localeconv



Get Numeric Formatting Convention Information

Portability: ISO/ANSI C conforming


SYNOPSIS
DESCRIPTION
RETURN VALUE
CAUTIONS
EXAMPLE


SYNOPSIS

#include <locale.h>

struct lconv *localeconv(void);


DESCRIPTION

localeconv sets the elements of an object of type struct lconv to the appropriate values for the formatting of numeric objects, both monetary and nonmonetary, with respect to the current locale.


RETURN VALUE

localeconv returns a pointer to a filled-in object of type struct lconv . The char * members of this structure may point to "" , indicating that the value is not available or is of 0 length. The char members are nonnegative numbers and can be equal to CHAR_MAX , indicating the value is not available. See The Locale Structure lconv for a discussion of each structure member returned by localeconv .


CAUTIONS

Another call to localeconv overwrites the previous value of the structure; if you need to reuse the previous value, be sure to save it. The following code saves the value of the structure:

struct lconv save_lconv;
save_lconv = *(localeconv());

Also, calls to setlocale with categories LC_ALL , LC_MONETARY , or LC_NUMERIC may overwrite the contents of the structure returned by localeconv .


EXAMPLE

The following example converts integer values to the format of a locale-dependent decimal picture string. frac_digits indicates how many digits are to the right of the decimal point character. If frac_digits is negative, the number is padded on the right, before the decimal point character, with the same number of 0s as the absolute value of frac_digits . It is assumed that the digit grouping string has at most only one element.

#include <stdio.h>
#include <string.h>
#include <locale.h>

size_t dec_fmt();
int main()

{
   struct lconv *lc;                 /* pointer to locale values */
   char buf[256];

   setlocale(LC_NUMERIC, "SAMP");   /* Use "SAMP" locale.        */

      /* Call localeconv to obtain locale conventions.           */
   lc = localeconv();

   dec_fmt(buf, lc, 12345678, 0);
   printf("The number is: 12,345,678. == %s\n", buf);

   dec_fmt(buf, lc, 12345678, 2);
   printf("The number is: 123,456.78 == %s\n", buf);

   dec_fmt(buf, lc, -12345678, 4);
   printf("The number is: -1,234.5678 == %s\n", buf);

   dec_fmt(buf, lc, 12345678, -5);
   printf("The number is: 1,234,567,800,000. == %s\n", buf);

   dec_fmt(buf, lc, 12345678,10);
   printf("The number is: 0.0012345678 == %s\n", buf);
}

size_t dec_fmt(char *buf, struct lconv *lc, int amt,
              int frac_digits)
{
   char numstr[128];        /* number string                     */
   char *ns_ptr,            /* number string pointer             */
      *buf_start;           /* output buffer start pointer       */
   int ngrp,                /* number of digits per group        */
      ntocpy,               /* digits to copy                    */
      non_frac;             /* number of nonfractional digits    */
   size_t ns_len;           /* number string length              */


   if (abs(frac_digits) > 100) /* Return error if too big        */
      return 0;
   buf_start = buf;

   sprintf(numstr, "%+-d", amt); /* Get amount as number string  */
   ns_ptr = numstr;              /* Point to number string       */
   ns_len = strlen(ns_ptr);      /* Get number string length     */
   if (frac_digits < 0) {   /* zero pad left of decimal point    */
      memset(ns_ptr + ns_len, '0', (size_t) -frac_digits);
      *(ns_ptr + ns_len - frac_digits) = '\0';
      ns_len -= frac_digits;      /* Add extra digit length.     */
      frac_digits = 0;
   }

      /* zero pad right of decimal point                             */
   if ((non_frac = ns_len - frac_digits - 1) < 0) {
      sprintf(numstr,"%+0*d", ns_len - non_frac + 1, amt);
      non_frac = 1;                /* e.g., 0.000012345678           */
   }

   if (amt < 0) *buf++ = *ns_ptr;  /* Insert sign in buffer.         */
      ns_ptr++;                    /* Skip +/- in number string.     */

       /* Convert grouping to int.                                   */
   if (!(ngrp = (int) *(lc->grouping)))
      ngrp = non_frac;             /* Use non_frac len if none.      */

      /* Get number of digits to copy for first group.               */
   if (!(ntocpy = non_frac % ngrp))
   ntocpy = ngrp;

   while (non_frac > 0) {         /* Separate groups of digits.      */
      memcpy(buf, ns_ptr, ntocpy); /* Copy digits.                   */
      ns_ptr += ntocpy;            /* Advance pointers.              */
      buf    += ntocpy;
      if (non_frac -= ntocpy) {       /* Insert separator and set    */
         *buf++ = *(lc->thousands_sep);/* number of digits for other */
         ntocpy = ngrp;                /* groups.                    */
      }
   }

   *buf++ = *(lc->decimal_point);      /* Insert decimal point.      */

   if (frac_digits > 0)
         /* Copy fraction + '\0' */
      memcpy(buf, ns_ptr, frac_digits + 1);
   else *buf = '\0';                  /* Else just null-terminate.   */
   return strlen(buf_start);           /* Return converted length.   */

}


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.