C String strxfrm() Function

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
<string.h> / <locale.h>

What You’ll Learn

The strxfrm() function transforms a string into a locale-specific sort key. Once transformed, plain strcmp() on the keys matches strcoll() on the originals—a powerful pattern when sorting long lists of names or words.

01

Sort key

Transform.

02

Locale

LC_COLLATE.

03

size_t

Length.

04

vs strcoll

Precompute.

05

Truncation

Check n.

06

Size query

NULL dest.

Definition and Usage

strxfrm (string transform) copies a transformed version of src into dest, using the collation rules of the current locale. The transformed bytes are not meant for display—they are a comparison key for sorting and searching.

The key property: for strings s1 and s2, strcmp(xfrm(s1), xfrm(s2)) has the same sign as strcoll(s1, s2) when both use the same locale.

💡
Beginner Tip

Call setlocale(LC_COLLATE, "") before strxfrm. Transform each string once, then sort with fast strcmp on the keys instead of calling strcoll repeatedly inside qsort.

📝 Syntax

Standard C declaration:

C
size_t strxfrm(char *dest, const char *src, size_t n);

Parameters

  • dest — buffer for the transformed string; may be NULL when n is 0 to query required length.
  • src — null-terminated source string to transform.
  • n — maximum number of bytes to write to dest, including the null terminator.

Return Value

  • Length of the full transformed string (excluding the null terminator).
  • If return value >= n (and n > 0), the result was truncated—resize dest and call again.

Headers

  • #include <string.h>
  • #include <locale.h> for setlocale(LC_COLLATE, ...)

⚡ Quick Reference

CallPurpose
strxfrm(dest, src, sizeof(dest))Transform into fixed buffer
len = strxfrm(NULL, src, 0)Query required byte length
strcmp(key1, key2)Compare transformed keys
return >= nBuffer too small (truncated)
Transform
strxfrm(dest, src, n)

Build key

Locale
setlocale(LC_COLLATE, "")

Setup

Compare keys
strcmp(k1, k2)

Fast sort

Direct
strcoll(s1, s2)

One-off

Examples Gallery

Compile with gcc strxfrm.c -std=c11 -o strxfrm. Transformed output may look identical to the source in the C locale but differs under locale-aware collation.

📚 Getting Started

Set the locale and transform a string into a destination buffer.

Example 1 — Transform a String

Transform "Café" as in the reference tutorial.

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

int main(void) {
    setlocale(LC_COLLATE, "");

    const char *source = "Caf\u00e9";
    char destination[16];

    size_t length = strxfrm(destination, source, sizeof(destination));

    printf("Transformed String: %s\n", destination);
    printf("Length of transformed string: %zu\n", length);

    return 0;
}

How It Works

The transformed text may look like the original when printed, but its byte sequence is arranged for locale-correct comparison. The return value is the full key length excluding the null terminator.

Example 2 — strcmp on Keys Matches strcoll

Verify the core property on two sample strings.

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

int main(void) {
    setlocale(LC_COLLATE, "");

    const char *s1 = "apple";
    const char *s2 = "Orange";
    char k1[64], k2[64];

    strxfrm(k1, s1, sizeof(k1));
    strxfrm(k2, s2, sizeof(k2));

    int via_coll = strcoll(s1, s2);
    int via_keys = strcmp(k1, k2);

    printf("strcoll sign: %d\n", via_coll > 0 ? 1 : via_coll < 0 ? -1 : 0);
    printf("strcmp keys:  %d\n", via_keys > 0 ? 1 : via_keys < 0 ? -1 : 0);

    return 0;
}

How It Works

Both comparisons agree on ordering sign. That is why sorting algorithms can compare precomputed keys with cheap strcmp instead of locale-heavy strcoll on every pass.

📈 Practical Patterns

Size buffers correctly, sort with keys, and handle truncation.

Example 3 — Query Required Buffer Size

Use dest = NULL and n = 0 before allocating memory.

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

int main(void) {
    setlocale(LC_COLLATE, "");

    const char *source = "Hello, locale sorting!";
    size_t need = strxfrm(NULL, source, 0);

    char *buf = malloc(need + 1);
    if (!buf) return 1;

    size_t wrote = strxfrm(buf, source, need + 1);

    printf("Need %zu bytes, wrote key length %zu\n", need, wrote);
    free(buf);

    return 0;
}

How It Works

The size query avoids guessing buffer sizes. Allocate need + 1 bytes so there is room for the terminating '\0'.

Example 4 — Sort Names Using Transformed Keys

Pre-transform, then sort with strcmp on keys.

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

typedef struct {
    const char *name;
    char key[32];
} Entry;

int entry_cmp(const void *a, const void *b) {
    const Entry *ea = (const Entry *)a;
    const Entry *eb = (const Entry *)b;
    return strcmp(ea->key, eb->key);
}

int main(void) {
    setlocale(LC_COLLATE, "");

    Entry list[] = {
        { "Zara", "" },
        { "apple", "" },
        { "Mari", "" }
    };
    size_t n = sizeof(list) / sizeof(list[0]);

    for (size_t i = 0; i < n; i++) {
        strxfrm(list[i].key, list[i].name, sizeof(list[i].key));
    }

    qsort(list, n, sizeof(Entry), entry_cmp);

    for (size_t i = 0; i < n; i++) {
        printf("%s\n", list[i].name);
    }

    return 0;
}

How It Works

Each name is transformed once into key. qsort compares keys with plain strcmp, which is the standard optimization pattern for locale-aware sorting.

Example 5 — Detect Truncation

Check the return value when the destination buffer is too small.

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

int main(void) {
    setlocale(LC_COLLATE, "");

    const char *source = "CodeToFun";
    char tiny[4];  /* too small on purpose */
    size_t n = sizeof(tiny);

    size_t len = strxfrm(tiny, source, n);

    if (len >= n) {
        printf("Truncated! Need at least %zu bytes (+1 for '\\0').\n", len + 1);
        printf("Partial dest: [%s]\n", tiny);
    }

    return 0;
}

How It Works

When len >= n, the key is incomplete and must not be used for sorting. Allocate at least len + 1 bytes and transform again.

🚀 Common Use Cases

  • Sorting name lists — pre-transform keys before qsort.
  • Dictionary indexes — build locale-correct ordering for lookup tables.
  • Database-style ordering — compare keys with fast byte-wise strcmp.
  • Internationalized UIs — sort menu items and file names for local users.
  • Pair with strcoll — use strcoll for one comparison, strxfrm for many.

🧠 How strxfrm() Works

1

Read locale rules

Use current LC_COLLATE settings.

Locale
2

Map src to key

Write transformed bytes into dest (up to n).

Transform
3

Return full length

Report total key size; flag truncation if >= n.

Result
=

Sort key

Compare with strcmp like strcoll on originals.

📝 Notes

  • Transformed strings are for comparison, not display to users.
  • Always set LC_COLLATE before transforming and comparing keys.
  • Check return value against n to detect truncation.
  • Key length can exceed strlen(src) depending on locale rules.
  • Works with strcoll() as the direct comparison counterpart.

⚡ Optimization

Transform each string once, then sort or search with strcmp. Calling strcoll inside a comparison function causes repeated locale work—strxfrm amortizes that cost across many comparisons. Store keys alongside data in structs for clean sorting code.

Conclusion

strxfrm() builds locale-aware sort keys so you can compare strings efficiently with strcmp. Set the collation locale, size buffers correctly, and pair it with strcoll() when you only need a single comparison.

You have reached the end of this string-function walkthrough—review the index for any functions you skipped.

💡 Best Practices

✅ Do

  • Call setlocale(LC_COLLATE, "") first
  • Query size with strxfrm(NULL, src, 0) when unsure
  • Check return >= n for truncation
  • Store keys in structs for sorting
  • Use strcmp on keys inside qsort

❌ Don’t

  • Display transformed keys to users
  • Sort truncated keys
  • Assume key length equals strlen(src)
  • Mix locales between transform and compare steps
  • Use strxfrm for a single compare—use strcoll

Key Takeaways

Knowledge Unlocked

Five things to remember about strxfrm()

Use these points for locale-aware sorting in C.

5
Core concepts
🌐 02

Locale

LC_COLLATE.

Setup
🔢 03

size_t len

Check n.

Safety
📈 04

vs strcoll

Precompute.

Compare
💬 05

strcmp keys

Fast sort.

Pattern

❓ Frequently Asked Questions

strxfrm() transforms a source string into a locale-specific form stored in dest. Comparing transformed strings with strcmp() gives the same ordering as strcoll() on the originals—useful when sorting many strings.
size_t strxfrm(char* dest, const char* src, size_t n); Include <string.h>. dest receives up to n bytes including the null terminator. Call setlocale(LC_COLLATE, "") before transforming for locale rules.
strcoll() compares two strings directly under locale rules. strxfrm() precomputes a sort key once; later strcmp() on keys is faster when you compare the same string many times (e.g. sorting).
The length of the full transformed string excluding the null terminator. If the return value is >= n, the result in dest was truncated—allocate a larger buffer and call again.
Yes. Pass dest as NULL and n as 0. strxfrm returns the length needed for the full transformed string (not counting the null byte). Allocate dest with length + 1 bytes.
Yes, for meaningful locale behavior. setlocale(LC_COLLATE, "") uses the environment locale. Without setting LC_COLLATE, the C locale is used and transformation often matches byte-wise ordering.
Did you know?

The C standard guarantees that if s1 collates before s2 under the current locale, then the transformed key for s1 compares less than the key for s2 using strcmp. That theorem is what makes the transform-then-sort pattern correct—not just a convenient hack.

Explore All C String Functions

Build locale sort keys with strxfrm(), then browse the full function index.

String Functions Index →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful