Skip to content
Laviyx Learn

Try

C course menu

String Functions in C: strlen, strcpy, strcat, strcmp, strchr, strstr and snprintf

Learn the C string library string.h: strlen, strcpy and strncpy, strcat, strcmp and why == does not compare strings, strchr and strstr for searching, strtok for splitting, building strings safely with snprintf, and converting text to numbers with strtol.

Beginner10 min readUpdated
On this page

<string.h> provides the standard functions for working with null-terminated strings. None of them know how big your arrays are, so you must make sure the destination has room.

Length, copy and join#

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

int main(void) {
    char full[40];
    const char *first = "Asha";
    const char *last = "Raman";

    strcpy(full, first);       /* copy */
    strcat(full, " ");         /* append */
    strcat(full, last);

    printf("%s\n", full);
    printf("length %zu, array size %zu\n", strlen(full), sizeof full);
    return 0;
}
Output
Asha Raman
length 10, array size 40

strlen counts characters before the '\0', so it is different from sizeof, the array's size in bytes.

strcpy and strcat write past the end of the destination if it is too small: a buffer overflow. Check the sizes first, or build strings with snprintf (below).

Comparing strings#

== compares two addresses, not the text. Use strcmp, which returns 0 when the strings are equal, a negative value if the first comes earlier in dictionary (character-code) order, and a positive value if it comes later:

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

int main(void) {
    char input[] = "admin";
    const char *role = "admin";

    printf("same text: %d\n", strcmp(input, role) == 0);
    printf("%d\n", strcmp("apple", "banana") < 0);
    printf("%d\n", strcmp("Zebra", "apple") < 0);   /* 'Z' (90) < 'a' (97) */
    printf("%d\n", strncmp("prefix-123", "prefix", 6) == 0);
    return 0;
}
Output
same text: 1
1
1
1

Uppercase letters have smaller character codes than lowercase ones, so strcmp sorts "Zebra" before "apple".

Searching#

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

int main(void) {
    const char *email = "student@example.com";

    const char *at = strchr(email, '@');          /* first '@' */
    if (at != NULL) {
        printf("domain: %s\n", at + 1);
        printf("user length: %d\n", (int)(at - email));
    }

    const char *found = strstr(email, "example");
    printf("%s\n", found ? "contains example" : "not found");
    return 0;
}
Output
domain: example.com
user length: 7
contains example

strchr and strstr return a pointer to the match, or NULL when there is none.

Splitting with strtok#

strtok splits a string into tokens. The first call gets the string; later calls pass NULL to continue. It modifies the string (it writes '\0' over the separators), so it needs a modifiable array, not a literal:

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

int main(void) {
    char line[] = "C,Java,Python,,SQL";
    for (char *tok = strtok(line, ","); tok != NULL; tok = strtok(NULL, ",")) {
        printf("[%s]\n", tok);
    }
    return 0;
}
Output
[C]
[Java]
[Python]
[SQL]

Empty fields (,,) are skipped, and strtok keeps hidden state, so you cannot split two strings at the same time with it.

Building strings safely with snprintf#

snprintf works like printf but writes into an array, never writing more than the size you give, and always adding '\0'. It returns the length the full text would have had, so you can detect truncation:

C
#include <stdio.h>

int main(void) {
    char label[32];
    int roll = 42;
    double score = 91.456;
    snprintf(label, sizeof label, "Roll %03d: %.1f%%", roll, score);
    printf("%s\n", label);

    char small[8];
    int needed = snprintf(small, sizeof small, "%s", "truncated text");
    printf("[%s] needed %d\n", small, needed);
    return 0;
}
Output
Roll 042: 91.5%
[truncat] needed 14

When the lengths are known at compile time, GCC even warns about this: '%s' directive output truncated.

Text to numbers#

atoi("42") is simple but cannot report errors (atoi("abc") returns 0). strtol tells you where the number stopped:

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

int main(void) {
    const char *inputs[] = {"250", "12abc", "abc"};
    for (int i = 0; i < 3; i++) {
        char *end;
        long value = strtol(inputs[i], &end, 10);
        if (end == inputs[i]) {
            printf("\"%s\": not a number\n", inputs[i]);
        } else if (*end != '\0') {
            printf("\"%s\": %ld, then extra text \"%s\"\n", inputs[i], value, end);
        } else {
            printf("\"%s\": %ld\n", inputs[i], value);
        }
    }
    return 0;
}
Output
"250": 250
"12abc": 12, then extra text "abc"
"abc": not a number

strtod does the same for floating-point numbers.

Quick reference#

FunctionDoes
strlen(s)Length, without the '\0'
strcpy(d, s) / strncpy(d, s, n)Copy (strncpy may leave no '\0': terminate it yourself)
strcat(d, s)Append
strcmp(a, b) / strncmpCompare: 0 when equal
strchr(s, c) / strrchrFirst / last occurrence of a character
strstr(s, sub)First occurrence of a substring
strtok(s, sep)Split into tokens (modifies s)
snprintf(buf, size, fmt, ...)Build a string safely
strtol / strtodParse numbers with error checking

Practice#

Practice exercise

Given char csv[] = "Asha,87;Ravi,92;Meena,78";, split it into records with ;, then split each record at the comma with strchr, and print the name with the highest mark.

Show solution
C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char csv[] = "Asha,87;Ravi,92;Meena,78";
    char best_name[20] = "";
    int best = -1;

    for (char *rec = strtok(csv, ";"); rec != NULL; rec = strtok(NULL, ";")) {
        char *comma = strchr(rec, ',');
        if (comma == NULL) continue;
        *comma = '\0';                         /* rec is now just the name */
        int mark = (int)strtol(comma + 1, NULL, 10);
        if (mark > best) {
            best = mark;
            snprintf(best_name, sizeof best_name, "%s", rec);
        }
    }
    printf("%s scored highest with %d\n", best_name, best);
    return 0;
}
Output
Ravi scored highest with 92

Key takeaway#

Finished this lesson?