C String strrchr() Function

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

What You’ll Learn

The strrchr() function finds the last occurrence of a character in a C-string. It is the reverse-direction partner of strchr()—perfect for file paths, extensions, and any task where the final match matters.

01

Last match

Right to left.

02

Returns ptr

Or NULL.

03

Suffix view

From match.

04

Read-only

No modify.

05

string.h

Standard C.

06

vs strchr

First match.

Definition and Usage

strrchr stands for string reverse char. It scans from the end of the string backward (conceptually) and returns a pointer to the last byte equal to c. Printing result with %s shows the suffix starting at that character.

Common jobs include finding the last path separator in /home/user/docs/report.pdf, the last dot before an extension, or the final delimiter in a log line.

💡
Beginner Tip

If you need the first match, use strchr. If you need the last, use strrchr. For binary buffers with a known length (not necessarily C-strings), consider memrchr where available.

📝 Syntax

Standard C declaration:

C
char *strrchr(const char *str, int c);

Parameters

  • str — null-terminated string to search.
  • c — character to find, passed as int (e.g. 'o' or '/').

Return Value

  • Pointer to the last occurrence of c in str.
  • NULL if c does not appear (except c == '\0', which always matches the terminator).

Header

  • #include <string.h>

⚡ Quick Reference

strcResult pointer atPrinting %s shows
"Hello, C Programming!"'o'last o in Programming"ogramming!"
"/home/user/file.txt"'/'final slash"/file.txt"
"archive.tar.gz"'.'last dot".gz"
indexif p != NULLp - str (zero-based position)
Last char
strrchr(str, c)

Final match

First char
strchr(str, c)

Initial match

Suffix
printf("%s", p)

From match

Check
if (p != NULL)

Before use

Examples Gallery

Compile with gcc strrchr.c -std=c11 -o strrchr. Each example checks for NULL before using the returned pointer.

📚 Getting Started

Find the final occurrence of a character and print the suffix.

Example 1 — Find the Last 'o'

From "Hello, C Programming!", locate the final letter o.

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

int main(void) {
    const char *text = "Hello, C Programming!";
    char searchChar = 'o';

    char *result = strrchr(text, searchChar);

    if (result != NULL) {
        printf("Last occurrence of '%c': %s\n", searchChar, result);
    } else {
        printf("'%c' not found in the string.\n", searchChar);
    }

    return 0;
}

How It Works

The first o is in Hello, but strrchr skips ahead to the o in Programming. The returned pointer starts a new C-string view: everything from that byte to the end.

Example 2 — Find the Last Path Separator

Split a Unix-style path into directory and filename at the final /.

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

int main(void) {
    const char *path = "/home/user/projects/main.c";

    char *slash = strrchr(path, '/');

    if (slash != NULL) {
        printf("Directory part: %.*s\n", (int)(slash - path), path);
        printf("File part:      %s\n", slash + 1);
    }

    return 0;
}

How It Works

slash + 1 skips past the separator to the basename. The length of the directory prefix is slash - path bytes—printed here with the %.*s precision format.

📈 Practical Patterns

Extensions, comparison with strchr, and missing characters.

Example 3 — Get the File Extension

Use the last . to isolate an extension (simple cases only).

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

int main(void) {
    const char *filename = "report.final.pdf";

    char *dot = strrchr(filename, '.');

    if (dot != NULL && dot[1] != '\0') {
        printf("Extension: %s\n", dot + 1);
    } else {
        printf("No extension found.\n");
    }

    return 0;
}

How It Works

The last dot separates pdf from report.final. Real path APIs handle edge cases (hidden files like .gitignore)—this shows the core strrchr idea.

Example 4 — strrchr() vs strchr()

Same string, same character—different end of the match.

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

int main(void) {
    const char *s = "ab-cd-ef";

    char *first = strchr(s, '-');
    char *last  = strrchr(s, '-');

    printf("strchr:  %s\n", first);
    printf("strrchr: %s\n", last);

    return 0;
}

How It Works

strchr stops at the first hyphen; strrchr at the second. Choose based on whether you care about the opening or closing delimiter.

Example 5 — Character Not Found

Handle NULL when the search character never appears.

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

int main(void) {
    const char *word = "CodeToFun";

    char *p = strrchr(word, 'z');

    if (p == NULL) {
        printf("'z' does not appear in \"%s\"\n", word);
    } else {
        printf("Found at: %s\n", p);
    }

    return 0;
}

How It Works

When no match exists, dereferencing the return value would crash. Always branch on NULL first.

🚀 Common Use Cases

  • File paths — find the last / or \ before the filename.
  • Extensions — locate the final . in a simple filename.
  • Log parsing — split at the last delimiter in a line.
  • URL handling — isolate the path segment after the final slash.
  • Teaching pointer views — suffix strings without copying memory.

🧠 How strrchr() Works

1

Find string end

Locate the terminating '\0'.

Length
2

Scan backward

Compare each byte to c from end toward start.

Search
3

Return last hit

Pointer to final match, or NULL if none.

Result
=

char* or NULL

Suffix view from the last matching character.

📝 Notes

  • Case-sensitive—'a' and 'A' differ.
  • Return pointer points into str; do not free() it.
  • strrchr(str, '\0') returns the terminator (same as end of string).
  • For Windows paths, also search '\\' or normalize separators first.
  • Not for binary blobs unless they are valid null-terminated C-strings.

⚡ Optimization

Standard library implementations scan at most once from the end. If you only need the string length, use strlen directly rather than strrchr(str, '\0'). For repeated searches on the same long string, cache the last known position when parsing incrementally.

Conclusion

strrchr() finds the last occurrence of a character and returns a pointer into the original string. Use it for path basenames, extensions, and suffix extraction—always check for NULL first.

Next, learn about the non-standard strrev() function for reversing strings in place.

💡 Best Practices

✅ Do

  • Check p != NULL before using the result
  • Use p - str for zero-based indexes
  • Use p + 1 to skip past a matched separator
  • Pair with strchr when you need both ends
  • Include <string.h>

❌ Don’t

  • Dereference a NULL return value
  • Assume the last dot is always the “real” extension
  • Modify memory through a const char* source
  • Use strrchr on non-null-terminated data
  • Confuse last match with first match—pick the right function

Key Takeaways

Knowledge Unlocked

Five things to remember about strrchr()

Use these points when the final character match matters.

5
Core concepts
📝 02

NULL safe

Check first.

Safety
🔢 03

Suffix view

Print %s.

Pattern
📈 04

vs strchr

First match.

Compare
💬 05

Paths

Last / .

Use case

❓ Frequently Asked Questions

strrchr() searches a null-terminated string for the last occurrence of a character. It returns a pointer to that character inside the string, or NULL if the character is not found.
char* strrchr(const char* str, int c); Include <string.h>. str is the string to search. c is the character to find, passed as int (often a char literal like '/').
strchr() returns a pointer to the first match scanning left to right. strrchr() returns a pointer to the last match. Use strrchr for the final '/' in a path or the last '.' before a file extension.
It returns NULL. Always check before dereferencing or using pointer subtraction.
Yes. strrchr(str, '\0') returns a pointer to the terminating null byte at the end of the string—equivalent to str + strlen(str). Searching for '\0' is rarely needed in application code.
Yes. 'o' and 'O' are different. For case-insensitive last-match search, walk the string yourself with tolower() comparisons or normalize case first.
Did you know?

GNU systems also provide memrchr, which searches a memory block of known length for a byte—useful when data is not null-terminated. Standard C gives you strrchr for C-strings and memchr for forward scans in fixed-size buffers.

Continue the String Functions Series

Find the last character with strrchr(), then explore in-place reversal with strrev().

Next: strrev() →

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