The strcoll() function compares two C-strings using the current locale's collation rules. Unlike strcmp(), which compares raw bytes, strcoll() can sort words the way users expect in their language—useful for contact lists, dictionaries, and localized UIs.
01
Locale Rules
LC_COLLATE.
02
Like strcmp
0 / <0 / >0.
03
setlocale
Configure first.
04
Sort Names
User-facing.
05
string.h
Standard C.
06
vs strcmp
Bytes vs locale.
Fundamentals
Definition and Usage
Collation is the set of rules that defines how characters and strings order in a language. The C standard provides strcoll so programs can respect those rules instead of assuming ASCII order.
Collation depends on setlocale(LC_COLLATE, ...). Call it once at startup (often with "" to use the user's environment) before relying on strcoll for sorting or equality checks in localized data.
💡
Beginner Tip
For internal identifiers, file extensions, or protocol keywords, stick with strcmp(). Reach for strcoll() when humans read the sorted output—names, titles, or dictionary entries.
#include <locale.h> — for setlocale and LC_COLLATE
Cheat Sheet
⚡ Quick Reference
Function
Compares by
When to use
strcmp
unsigned byte values
ASCII tokens, fast internal compares
strcoll
current LC_COLLATE locale
sorting names for users
strcasecmp
case-folded bytes (POSIX)
commands, not full locale rules
strxfrm + strcmp
precomputed sort keys
sorting many strings efficiently
Compare
strcoll(s1, s2)
Locale order
Equal?
strcoll(a, b) == 0
Collation match
Setup
setlocale(LC_COLLATE, "")
Required
C locale
setlocale(LC_COLLATE, "C")
Like strcmp
Hands-On
Examples Gallery
Compile with gcc strcoll.c -std=c11 -o strcoll. Output can vary slightly by platform locale data—set LANG or call setlocale explicitly for reproducible results.
📚 Getting Started
Set the locale, then compare two strings with strcoll.
Example 1 — Locale-Aware Comparison
Compare "apple" and "Orange" after setting the environment locale.
C
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main(void) {
setlocale(LC_COLLATE, "");
const char *s1 = "apple";
const char *s2 = "Orange";
int result = strcoll(s1, s2);
if (result < 0) {
printf("%s comes before %s in the current locale.\n", s1, s2);
} else if (result > 0) {
printf("%s comes after %s in the current locale.\n", s1, s2);
} else {
printf("%s and %s are equivalent in the current locale.\n", s1, s2);
}
return 0;
}
📤 Output:
apple comes after Orange in the current locale.
How It Works
Many English locales treat uppercase letters as sorting before lowercase when comparing the first character ('O' vs 'a'). The exact ordering depends on installed locale data—always test on your target system.
Example 2 — strcoll() vs strcmp()
See both functions side by side on the same pair of strings.
Under the "C" locale, strcoll typically matches strcmp for these ASCII strings. With a user locale, results can diverge for accented letters or language-specific rules.
📈 Practical Patterns
Sorting and using strcoll as a comparison callback.
Example 3 — Sort a Name List
Sort strings for display using locale collation rules.
C
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main(void) {
const char *names[] = { "Zoe", "andré", "Bob", "Álvarez" };
int i, j, n = 4;
const char *tmp;
setlocale(LC_COLLATE, "");
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (strcoll(names[i], names[j]) > 0) {
tmp = names[i];
names[i] = names[j];
names[j] = tmp;
}
}
}
for (i = 0; i < n; i++) {
printf("%s\n", names[i]);
}
return 0;
}
📤 Output (example, locale-dependent):
andré
Álvarez
Bob
Zoe
How It Works
Each swap uses strcoll instead of strcmp, so accented characters order according to locale rules rather than raw UTF-8 byte values. Exact order varies by locale—test with your users' settings.
Example 4 — Force the C Locale
When you need predictable byte-like ordering, set the C locale explicitly.
Version strings and internal keys often should not use language collation. The C locale gives stable, byte-wise ordering suitable for machine-readable identifiers.
Example 5 — qsort() with strcoll
Pass a wrapper that calls strcoll for standard library sorting.
qsort needs a comparator returning negative, zero, or positive—exactly what strcoll provides. Call setlocale before sorting so every comparison uses the same rules.
Applications
🚀 Common Use Cases
Contact lists — sort names for the user's language.
Dictionary / glossary apps — alphabetical order with accents.
File browsers — localized file name sorting (with caveats for mixed scripts).
Database export previews — present sorted text columns correctly.
Testing i18n — verify ordering under different LC_COLLATE settings.
🧠 How strcoll() Works
1
Read LC_COLLATE locale
Uses rules installed for the active locale.
Locale
2
Compare s1 and s2
Apply collation weights—not just raw char values.
Collation
3
Return ordering sign
0 if equivalent; otherwise less or greater.
Result
=
🌐
int result
Human-meaningful order for the active locale.
Important
📝 Notes
Call setlocale(LC_COLLATE, ...) before relying on locale-specific order.
Slower than strcmp—use strxfrm when sorting large lists repeatedly.
Strings should be valid UTF-8 (or the locale encoding) on modern systems.
Collation results can differ between operating systems and locale packages.
Not a substitute for Unicode-aware libraries when full i18n is required.
Performance
⚡ Optimization
When sorting thousands of strings, transform each once with strxfrm() into a buffer, then compare keys with strcmp. That avoids repeating expensive locale work inside every comparison during qsort.
Wrap Up
Conclusion
strcoll() compares strings using locale collation rules set by LC_COLLATE. Use it for user-visible sorting; use strcmp() for internal byte-wise compares.
Explore strxfrm() next when you need efficient bulk sorting with the same locale rules.
Call setlocale(LC_COLLATE, "") at program startup for UI sorting
Use strcoll for human-readable name lists
Test with your target locales and encodings
Consider strxfrm for large sort operations
Fall back to strcmp for protocol tokens and IDs
❌ Don’t
Assume strcoll matches strcmp on all strings
Sort without setting LC_COLLATE first
Use strcoll for case-insensitive command matching (use strcasecmp)
Expect identical ordering on every OS
Pass NULL pointers—behavior is undefined
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about strcoll()
Use these points when comparing strings for users.
5
Core concepts
🌐01
Locale Order
Not raw bytes.
Basics
📝02
setlocale
LC_COLLATE.
Setup
🔢03
Like strcmp
0 / sign.
Return
📈04
Sort UI
Names, lists.
Use case
💬05
vs strcmp
Fast bytes.
Compare
❓ Frequently Asked Questions
strcoll() compares two null-terminated strings according to the current locale collation rules (LC_COLLATE). It returns 0 if they are equivalent under those rules, a negative value if s1 sorts before s2, or a positive value if s1 sorts after s2.
int strcoll(const char* s1, const char* s2); Include <string.h>. Call setlocale(LC_COLLATE, "") or a specific locale like "en_US.UTF-8" before comparing so strcoll uses the intended language rules.
strcmp() compares raw byte values and is fast but not locale-aware. strcoll() applies locale collation—important for sorting names and words correctly for users in different languages. For plain ASCII tokens, strcmp is usually enough.
Yes, for meaningful locale-specific behavior. setlocale(LC_COLLATE, "") picks the environment locale. Without setting LC_COLLATE, the C locale is used and strcoll often behaves like a byte-wise compare similar to strcmp.
Same sign convention as strcmp: 0 for equal under collation rules, less than 0 if s1 is before s2, greater than 0 if s1 is after s2. Only the sign is reliably portable for ordering.
strxfrm() transforms a string into a sort key using the current collation rules. You can strcmp() the transformed keys for repeated comparisons—useful when sorting many strings and strcoll would be called often.
Did you know?
The companion function strxfrm() builds a locale-aware sort key. Sorting with strcmp on transformed keys can be much faster than calling strcoll repeatedly inside qsort—similar idea to normalizing strings once before comparing many times.