C String Functions

C string functions are library functions that work with null-terminated character arrays. They let you measure, compare, copy, join, search, and split text without writing every loop yourself. Because C strings are just bytes ending at '\0', these functions are useful but also require careful buffer management.

Most common string functions live in <string.h>. To use them well, you need to know what each function assumes about memory, what it returns, and which functions can write past a buffer if you pass the wrong size.

Overview: How C String Functions Work

A C string is a sequence of char values followed by a null terminator, '\0'. Functions such as strlen, strcmp, strcpy, and strcat do not receive a hidden length value. They start at the pointer you pass and examine characters until they find the terminator.

This explains both the power and the danger. A call like strlen(name) is simple because it only needs the address of the first character. Internally it checks name[0], then name[1], and continues until it reaches zero. But if name is not properly terminated, strlen keeps reading memory that does not belong to the string. That is undefined behavior.

Functions that write into a destination buffer need even more attention. strcpy(destination, source) copies all characters from source, including the null terminator, into destination. It does not know how large destination is. If the destination array is too small, the copy overflows the buffer. strcat has the same issue when appending: it must find the current terminator in the destination, then write more characters after it.

For that reason, serious C code usually pairs string functions with explicit size checks, or uses size-aware functions such as snprintf when building formatted strings. The standard functions are not bad; they are low-level. They trust you to pass valid, terminated strings and sufficiently large writable arrays.

String comparison is also different from numeric comparison. You cannot compare string contents with == unless you only want to know whether two pointers hold the same address. Use strcmp to compare the text. It returns 0 for equal strings, a negative value if the first string sorts before the second, and a positive value if it sorts after.

Syntax

#include <string.h>

size_t strlen(const char *s);
int strcmp(const char *a, const char *b);
char *strcpy(char *destination, const char *source);
char *strcat(char *destination, const char *source);
char *strchr(const char *s, int ch);
char *strstr(const char *s, const char *needle);
char *strtok(char *s, const char *delimiters);
Function Use Important Detail
strlen Counts characters before '\0'. Does not include the terminator.
strcmp Compares two strings lexicographically. Test equality with == 0.
strcpy Copies one string into a writable buffer. Destination must be large enough.
strcat Appends one string to the end of another. Destination must already contain a valid string.
strchr Finds the first occurrence of one character. Returns NULL if not found.
strstr Finds the first occurrence of a substring. Returns a pointer into the original string.
strtok Splits a modifiable string into tokens. Changes the string by writing terminators.

The type size_t is an unsigned integer type used for sizes and counts. It is the return type of strlen, so print it with %zu.

Examples

Measure And Compare Strings

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

int main(void) {
    const char word[] = "lemon";
    const char first[] = "apple";
    const char second[] = "lemon";

    printf("word: %s\n", word);
    printf("length: %zu\n", strlen(word));

    if (strcmp(second, first) > 0) {
        printf("%s comes after %s\n", second, first);
    }

    if (strcmp(word, second) == 0) {
        printf("same text\n");
    }

    return 0;
}

Output:

word: lemon
length: 5
lemon comes after apple
same text

strlen counts the five visible letters in lemon. It does not count the hidden terminator. strcmp compares character values from left to right. The result is positive because lemon sorts after apple, and it is zero when both strings contain the same characters in the same order.

Copy And Join Strings Safely

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

int main(void) {
    const char first[] = "Ada";
    const char last[] = "Lovelace";
    char full[32] = "";

    size_t needed = strlen(first) + 1 + strlen(last) + 1;

    if (needed <= sizeof full) {
        strcpy(full, first);
        strcat(full, " ");
        strcat(full, last);
        printf("Full name: %s\n", full);
    } else {
        printf("Buffer too small\n");
    }

    printf("Characters used: %zu\n", strlen(full));
    printf("Buffer size: %zu\n", sizeof full);

    return 0;
}

Output:

Full name: Ada Lovelace
Characters used: 12
Buffer size: 32

This example uses strcpy and strcat, but only after calculating the required size. The required size includes the first name, one space, the last name, and one byte for '\0'. The destination starts as an empty string, so strcat can find a valid terminator before appending.

Search For Characters And Substrings

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

int main(void) {
    const char email[] = "ada@example.com";
    const char sentence[] = "C strings use a null terminator";

    const char *at = strchr(email, '@');
    const char *domain = strstr(email, "example");
    const char *word = strstr(sentence, "null");

    if (at != NULL) {
        printf("Username length: %td\n", at - email);
        printf("Domain starts: %s\n", at + 1);
    }

    if (domain != NULL) {
        printf("Found domain word: %s\n", domain);
    }

    if (word != NULL) {
        printf("Found phrase: %s\n", word);
    }

    return 0;
}

Output:

Username length: 3
Domain starts: example.com
Found domain word: example.com
Found phrase: null terminator

strchr returns a pointer to the matching character inside the original string. Subtracting the beginning pointer from that pointer gives the zero-based position. strstr works similarly, but it searches for a whole substring. Printing from the returned pointer prints from that location to the string’s terminator.

Split A String Into Tokens

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

int main(void) {
    char line[] = "red,green,blue";
    char *token = strtok(line, ",");
    int count = 0;

    while (token != NULL) {
        count++;
        printf("Color %d: %s\n", count, token);
        token = strtok(NULL, ",");
    }

    printf("Total: %d\n", count);

    return 0;
}

Output:

Color 1: red
Color 2: green
Color 3: blue
Total: 3

strtok is different from the other search functions because it modifies the array. It replaces delimiters with '\0' so each token becomes its own C string. That is why line must be a writable array, not a string literal.

How It Works Step By Step

  1. The program includes <string.h>, which declares the string functions.
  2. A function receives a pointer to the first character of a string.
  3. For reading functions, it advances through memory until it finds '\0' or the searched text.
  4. For writing functions, it copies bytes into the destination and writes a final '\0'.
  5. The caller is responsible for making sure each input is a valid string and each destination has enough space.

Consider strcat(full, last). First, the function scans full until it finds the current terminator. Then it starts writing characters from last at that position. Finally it copies the terminator from last, so the combined result is still a valid string. If full has no terminator, or if there is not enough space after it, the behavior is undefined.

Common Mistakes

Using == To Compare Text

name == "Ada" compares addresses, not string contents. It may be false even when the visible text is the same. Use strcmp(name, "Ada") == 0 when you mean equal text.

Copying Into A Buffer Without Checking The Size

strcpy does not protect the destination. Before copying, make sure strlen(source) + 1 <= sizeof destination while destination is still an actual array in the same scope. In function parameters, pass the destination capacity separately.

Using strcat On Uninitialized Storage

strcat must find the existing end of the destination string. A local array like char buffer[40]; contains indeterminate bytes until initialized. Start it with char buffer[40] = ""; or write a valid string into it before appending.

Calling strtok On A String Literal

strtok writes '\0' characters into the input. A literal such as "red,green" should not be modified. Use char colors[] = "red,green"; so the data is stored in a writable array.

Best Practices

  • Include <string.h> whenever you use standard string functions.
  • Remember that strlen is text length, not buffer capacity.
  • Use strcmp(a, b) == 0 for equality, and test only the sign for ordering.
  • Check destination capacity before strcpy or strcat.
  • Initialize append buffers with an empty string before using strcat.
  • Prefer snprintf for building formatted strings because it receives the destination size.
  • Check search results against NULL before dereferencing or printing from them.
  • Use writable arrays for functions that modify strings, especially strtok.
  • Pass buffer sizes into helper functions; do not try to recover array size from a pointer parameter.

Practice Exercises

  1. Write a program that compares two passwords stored in arrays and prints whether they match. Use strcmp.
  2. Create a char title[40], copy a short course name into it, append " tutorial", and print the final string after checking the required size.
  3. Given "first:last:score", use strtok to print each field on its own line.

Summary

  • C string functions operate on null-terminated char arrays.
  • strlen counts characters before the terminator, while sizeof reports array storage only when the array is in scope.
  • strcmp compares string contents; == compares pointer values.
  • strcpy and strcat require destinations large enough for all characters plus '\0'.
  • strchr and strstr return pointers into the original string or NULL.
  • strtok splits text by modifying a writable array.