Previous Page
Next Page


Transforms a wide string for easier locale-specific comparison

#include <wchar.h>
size_t wcsxfrm ( wchar_t * restrict dest , const wchar_t * restrict src ,
                size_t n  );

The wcsxfrm( ) function transforms the wide string addressed by src, and copies the result to the wchar_t array addressed by dest. The third argument, n, specifies a maximum number of wide characters (including the terminating null wide character) that the function may write to dest. The locations that wcsxfrm( ) reads from and writes to using its restricted pointer parameters must not overlap.

The transformation performed depends on the value of the locale category LC_COLLATE, which you can query or set using the setlocale( ) function. Furthermore, the wcsxfrm( ) transformation is related to the wcscoll( ) function in the following way: if you use wcscmp( ) to compare two strings produced by wcsxfrm( ) calls, the result is the same as if you use wcscoll( ) to compare the original strings passed to wcsxfrm( ). Using wcsxfrm( ) and wcscmp( ) may be more efficient than wcscoll( ) if you need to use the same string in many comparisons.

The wcsxfrm( ) function returns the length of the transformed version of the string, not counting the terminating null character. If this length is greater than or equal to n, then the contents of the array at dest are indeterminate. The value of n may also be 0, in which case dest may be a null pointer.


typedef struct stringpair { wchar_t * original;
                            wchar_t * xformed;
                          } Stringpair_t ;

int stringpaircmp( const void *p1, const void *p2 );

int main( )
  wchar_t *originals[ ] = { L"Chávez", L"Carron",  L"Canoso",
                           L"Cañoso", L"Carteño", L"Corriando",
                           L"Carilo", L"Carillón", };
  wchar_t xformbuffer[1024];

  /* Make an array of structures out of the strings and their
     xformations */

  const int elementcount = sizeof(originals) / sizeof(wchar_t *);
  Stringpair_t stringpairs[elementcount];

  setlocale( LC_ALL, "es_US.UTF-8" );       // Set the locale to US Spanish
  wprintf( L"Sorting order in the locale %s:\n",
           setlocale( LC_COLLATE, NULL ));

  for ( int i = 0; i < elementcount ; i++ )
    stringpairs[i].original = originals[i];
                      = malloc( wcsxfrm( xformbuffer, originals[i], 1024 ));
    if ( stringpairs[i].xformed != NULL )
      wcscpy( stringpairs[i].xformed, xformbuffer );

  qsort( stringpairs, elementcount, sizeof(Stringpair_t), stringpaircmp );

  for ( int i = 0; i < elementcount ; i++ )
    fputws( stringpairs[i].original, stdout );
    fputwc( L'\n', stdout );
} // end of main( )

/* A comparison function for use by qsort. Uses wcscmp( ) rather
 * that wcscoll( ), assuming strings are paired with their wcsxfrm( )
 * results in a Stringpair_t structure.
int stringpaircmp( const void *p1, const void *p2 )
  const Stringpair_t * sp1 = (Stringpair_t *)p1;
  const Stringpair_t * sp2 = (Stringpair_t *)p2;

  return wcscmp( sp1->xformed, sp2->xformed );

This code produces the following output:

Sorting order in the locale es_US.UTF-8:

See Also

wcscoll( ), wcscmp( ), strxfrm( ), setlocale( )

Previous Page
Next Page