C String strlwr() Function

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
Extension / <ctype.h>

What You’ll Learn

The strlwr() function converts uppercase letters in a C-string to lowercase in place. It is not ISO C standard—many compilers expose it as an extension (often as _strlwr on Windows). This tutorial also shows the portable tolower() loop every platform supports.

01

Lowercase

A → a.

02

In Place

Modifies str.

03

Returns str

Same pointer.

04

Not ISO C

Extension.

05

tolower

Portable.

06

vs strupr

Uppercase.

Definition and Usage

strlwr stands for string lower. It scans a null-terminated string and replaces each uppercase ASCII letter with its lowercase form. Digits, spaces, punctuation, and already-lowercase letters stay the same.

Because it modifies the buffer you pass in, copy the string first if you need to preserve the original text. Never pass a string literal—that memory is read-only and modifying it causes undefined behavior.

💡
Beginner Tip

For case-insensitive comparison only, consider strcasecmp() or _stricmp() instead of changing the string. Use lowercasing when you need normalized storage (keys in a table, canonical filenames).

📝 Syntax

Typical extension declaration:

C
char *strlwr(char *str);
/* MSVC documented form: */
char *_strlwr(char *str);

Portable alternative

C
#include <ctype.h>

void str_to_lower(char *s) {
    for (; *s; s++) {
        *s = (char)tolower((unsigned char)*s);
    }
}

Parameter

  • str — writable null-terminated string to convert.

Return Value

  • Returns str (pointer to the modified buffer).

⚡ Quick Reference

BeforeAfter strlwr / tolower loop
"Hello, C Programming!""hello, c programming!"
"ABC123""abc123"
"already lower""already lower" (unchanged)
writable bufferrequired (not string literal)
portabletolower((unsigned char)c) per byte
Extension
strlwr(buf);

If available

MSVC
_strlwr(buf);

Windows

Portable
str_to_lower(buf);

tolower loop

Compare only
strcasecmp(a, b)

No modify

Examples Gallery

Examples use the portable tolower helper so they compile on Linux, macOS, and Windows. Where _strlwr exists, it behaves the same way in place.

📚 Getting Started

Lowercase every letter in a writable char array.

Example 1 — Convert to Lowercase (Portable)

Turn "Hello, C Programming!" into all lowercase.

C
#include <stdio.h>
#include <ctype.h>

void str_to_lower(char *s) {
    for (; *s; s++) {
        *s = (char)tolower((unsigned char)*s);
    }
}

int main(void) {
    char text[] = "Hello, C Programming!";

    str_to_lower(text);

    printf("Lowercase String: %s\n", text);

    return 0;
}

How It Works

Each byte is passed to tolower. Casting to unsigned char avoids undefined behavior if a byte is negative on platforms where char is signed.

Example 2 — Preserve the Original String

Copy into a buffer, then lowercase the copy.

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

void str_to_lower(char *s) {
    for (; *s; s++) {
        *s = (char)tolower((unsigned char)*s);
    }
}

int main(void) {
    const char *original = "Hello, C Programming!";
    char buffer[50];

    strcpy(buffer, original);
    str_to_lower(buffer);

    printf("Original:  %s\n", original);
    printf("Lowercase: %s\n", buffer);

    return 0;
}

How It Works

strlwr always mutates its argument. Copying with strcpy first keeps the source literal unchanged while you normalize the working copy.

📈 Practical Patterns

Normalize user text, understand tolower, and MSVC naming.

Example 3 — Normalize a Command Token

Lowercase user input before storing or hashing a key.

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

void str_to_lower(char *s) {
    for (; *s; s++) {
        *s = (char)tolower((unsigned char)*s);
    }
}

int main(void) {
    char cmd[] = "QuIt";

    str_to_lower(cmd);

    if (strcmp(cmd, "quit") == 0) {
        printf("Goodbye!\n");
    } else {
        printf("Unknown: %s\n", cmd);
    }

    return 0;
}

How It Works

After lowercasing, a simple case-sensitive strcmp against "quit" succeeds. Alternatively use strcasecmp and skip modifying the string.

Example 4 — tolower() on One Character

See what changes and what stays the same.

C
#include <stdio.h>
#include <ctype.h>

int main(void) {
    char letters[] = "A b C";

    for (int i = 0; letters[i]; i++) {
        unsigned char c = (unsigned char)letters[i];
        printf("'%c' -> '%c'  ", letters[i], (char)tolower(c));
    }
    printf("\n");

    return 0;
}

How It Works

tolower only affects uppercase letters in the current C locale. Spaces and lowercase letters pass through unchanged—that is exactly what strlwr does across a whole string.

Example 5 — Using _strlwr() on Windows

When your toolchain provides the extension, call it directly on a writable buffer.

C
/* Windows / MSVC example */
#include <stdio.h>
#include <string.h>

int main(void) {
    char buf[] = "Hello, C Programming!";

#if defined(_MSC_VER)
    _strlwr(buf);
    printf("Lowercase: %s\n", buf);
#else
    printf("_strlwr is not available on this platform.\n");
    printf("Use the portable tolower loop instead.\n");
#endif

    return 0;
}

How It Works

_strlwr modifies buf in place and returns the same pointer. Guard with preprocessor checks so Linux CI builds still compile.

🚀 Common Use Cases

  • Canonical keys — store map or dictionary keys in one case.
  • User commands — normalize input before lookup.
  • Filename handling — on case-insensitive file systems.
  • Simple parsers — treat TRUE and true alike after folding.
  • Teaching — connect character functions to whole-string transforms.

🧠 How strlwr() Works

1

Start at str[0]

Walk until '\0'.

Scan
2

Apply tolower

Replace uppercase ASCII letters in place.

Fold
3

Leave others alone

Digits, space, punctuation unchanged.

Skip
=

char* str

Same buffer, now lowercase letters.

📝 Notes

  • Not part of ISO C—verify availability or use a tolower loop.
  • Modifies the string in place; copy first if needed.
  • Never pass string literals or read-only memory.
  • Locale-dependent for non-ASCII; not full Unicode case mapping.
  • Pair conceptually with strupr() for the reverse transform.

⚡ Optimization

Lowercasing is O(n) in string length. For occasional normalization the simple loop is fine. Avoid repeated lowercasing of the same unchanged string in hot loops—cache the result or compare with case-insensitive helpers instead.

Conclusion

strlwr() lowercases a string in place where the extension exists. Learn the portable tolower loop for every platform, and prefer case-insensitive compare functions when you do not need to mutate text.

Next, learn strupr() to convert strings to uppercase.

💡 Best Practices

✅ Do

  • Use a writable char array or heap buffer
  • Cast to unsigned char before tolower
  • Copy the original when you must preserve it
  • Prefer strcasecmp for compare-only tasks
  • Wrap platform calls in #ifdef for portability

❌ Don’t

  • Call strlwr on string literals
  • Assume strlwr exists on every compiler
  • Expect Unicode full case fold from plain tolower
  • Lowercase passwords for “security”
  • Forget that the original buffer is overwritten

Key Takeaways

Knowledge Unlocked

Five things to remember about strlwr()

Use these points when changing string case in C.

5
Core concepts
📝 02

Extension

Not ISO C.

Portability
🔢 03

tolower

Portable.

Pattern
📈 04

Copy First

Keep original.

Safety
💬 05

vs strupr

Uppercase.

Compare

❓ Frequently Asked Questions

strlwr() converts every uppercase letter in a string to lowercase, modifying the string in place. It returns a pointer to the same buffer. Non-letter characters are left unchanged.
No. strlwr() is a compiler-specific extension (common on older Microsoft and Borland toolchains). ISO C does not define it. For portable code, write a loop with tolower() from <ctype.h>.
tolower() converts one character. strlwr() (where available) converts an entire null-terminated string in place. A portable helper loops over each byte and applies tolower().
No. String literals are read-only. strlwr() modifies memory, so pass a writable char array or heap buffer.
Microsoft documents _strlwr() in <string.h>. Some environments also expose strlwr as an alias. Check your compiler documentation.
You can, but functions like strcasecmp() (POSIX) or _stricmp() (Windows) compare without modifying either string. Lowercasing is useful when you need normalized storage, not just a one-time compare.
Did you know?

The old reference incorrectly listed strlwr in standard <string.h>. It is a vendor extension. The C standard gives you tolower and toupper in <ctype.h> for single characters—whole-string case functions are left to libraries or your own short loops.

Continue the String Functions Series

Lowercase strings with strlwr() concepts, then learn uppercase conversion with strupr().

Next: strupr() →

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