The C standard library provides a complete set of string functions in <string.h>. Unlike higher-level languages, C strings are just null-terminated arrays of char — there is no built-in string type, so these functions do the work that other languages bake into the runtime. This guide covers every function you will use regularly, with a working example for each.
Quick Reference Table
| Function | What it does |
|---|---|
strlen(s) |
Returns the length of string s (not counting \0) |
strcpy(dst, src) |
Copies src into dst (unsafe — prefer strncpy) |
strncpy(dst, src, n) |
Copies at most n bytes from src to dst |
strcat(dst, src) |
Appends src to the end of dst |
strncat(dst, src, n) |
Appends at most n bytes of src to dst |
strcmp(s1, s2) |
Compares two strings; returns 0 if equal |
strncmp(s1, s2, n) |
Compares first n characters only |
strchr(s, c) |
Finds first occurrence of character c in s |
strrchr(s, c) |
Finds last occurrence of character c in s |
strstr(hay, needle) |
Finds first occurrence of substring needle in hay |
strtok(s, delim) |
Splits a string into tokens by delimiter characters |
sprintf(buf, fmt, ...) |
Writes formatted output into a char buffer |
memset(s, c, n) |
Fills first n bytes of s with value c |
memcpy(dst, src, n) |
Copies n bytes from src to dst (no overlap) |
strlen — String Length
Returns the number of characters before the null terminator. The null byte itself is not counted.
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "Hello, World!";
printf("Length: %zu\n", strlen(s)); /* 13 */
char empty[] = "";
printf("Empty length: %zu\n", strlen(empty)); /* 0 */
return 0;
}
Length: 13
Empty length: 0
Note: strlen returns size_t (an unsigned type). Use %zu to print it. Comparing strlen(s) - 1 with an unsigned type can wrap around to a huge number when the string is empty — always check strlen(s) > 0 before subtracting.
strcpy and strncpy — Copy a String
strcpy copies the source string including its null terminator into the destination. The destination buffer must be large enough — strcpy does not check, making it unsafe for unknown inputs. Use strncpy with a length limit instead.
#include <stdio.h>
#include <string.h>
int main(void)
{
char src[] = "C Programming";
char dst[20];
/* strncpy: copy at most sizeof(dst)-1 chars, then force-terminate */
strncpy(dst, src, sizeof(dst) - 1);
dst[sizeof(dst) - 1] = '\0';
printf("Copied: %s\n", dst);
return 0;
}
Copied: C Programming
Why force-terminate? strncpy pads with null bytes when src is shorter than n, but it does not null-terminate when src is longer than n. Always write dst[n - 1] = '\0' after calling strncpy.
strcat and strncat — Concatenate Strings
strcat appends the source string to the end of the destination. The destination must have room for both strings plus a null terminator. strncat limits how many characters are appended and always null-terminates.
#include <stdio.h>
#include <string.h>
int main(void)
{
char greeting[30] = "Hello";
char name[] = ", World!";
/* strncat: append at most n chars, always null-terminates */
strncat(greeting, name, sizeof(greeting) - strlen(greeting) - 1);
printf("%s\n", greeting);
return 0;
}
Hello, World!
strcmp and strncmp — Compare Strings
Returns 0 if equal, a negative value if s1 < s2, positive if s1 > s2 (lexicographic order). Never compare strings with == — that compares pointers, not content.
#include <stdio.h>
#include <string.h>
int main(void)
{
char a[] = "apple";
char b[] = "apple";
char c[] = "banana";
printf("a vs b: %d\n", strcmp(a, b)); /* 0 — equal */
printf("a vs c: %d\n", strcmp(a, c)); /* <0 — 'a' < 'b' */
printf("c vs a: %d\n", strcmp(c, a)); /* >0 — 'b' > 'a' */
/* strncmp: compare only first 3 characters */
printf("ban vs bat (3): %d\n", strncmp("banana", "battery", 3)); /* 0 */
return 0;
}
a vs b: 0
a vs c: -1
c vs a: 1
ban vs bat (3): 0
strchr and strrchr — Find a Character
strchr returns a pointer to the first occurrence of a character. strrchr returns the last. Both return NULL if the character is not found.
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "c-program-example.com";
char *first = strchr(s, '-');
char *last = strrchr(s, '.');
if (first) printf("First '-' at position: %td\n", first - s);
if (last) printf("Last '.' at position: %td\n", last - s);
return 0;
}
First '-' at position: 1
Last '.' at position: 17
strstr — Find a Substring
Returns a pointer to the first occurrence of needle inside haystack, or NULL if not found.
#include <stdio.h>
#include <string.h>
int main(void)
{
char haystack[] = "The C Programming Language";
char needle[] = "Programming";
char *pos = strstr(haystack, needle);
if (pos)
printf("Found \"%s\" at position %td\n", needle, pos - haystack);
else
printf("Not found.\n");
return 0;
}
Found "Programming" at position 6
strtok — Split a String into Tokens
strtok modifies the original string by replacing delimiter characters with null bytes. Call it repeatedly with NULL as the first argument to get subsequent tokens.
#include <stdio.h>
#include <string.h>
int main(void)
{
char csv[] = "Alice,Bob,Charlie,Diana";
char *token;
token = strtok(csv, ",");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ",");
}
return 0;
}
Alice
Bob
Charlie
Diana
Caution: strtok is not reentrant — it uses internal static state. If you need to tokenise two strings in parallel, use strtok_r (POSIX) which takes an explicit state pointer.
sprintf — Print to a String Buffer
Works exactly like printf but writes into a char array instead of stdout. Useful for building strings dynamically.
#include <stdio.h>
int main(void)
{
char buf[64];
int score = 95;
sprintf(buf, "Your score is %d out of 100.", score);
printf("%s\n", buf);
return 0;
}
Your score is 95 out of 100.
memset and memcpy — Raw Memory Operations
These work on bytes, not characters, so they apply to any data type — not just strings.
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[10];
int src[4] = {1, 2, 3, 4};
int dst[4];
int i;
/* memset: fill buffer with a single byte value */
memset(buf, 0, sizeof(buf)); /* zero entire buffer */
memset(buf, '*', 5); /* fill first 5 bytes with '*' */
buf[5] = '\0';
printf("memset result: %s\n", buf);
/* memcpy: copy raw bytes (no overlap allowed) */
memcpy(dst, src, sizeof(src));
for (i = 0; i < 4; i++)
printf("%d ", dst[i]);
printf("\n");
return 0;
}
memset result: *****
1 2 3 4
Common Mistakes and Safety Rules
| Mistake | Safe alternative |
|---|---|
if (s1 == s2) to compare strings |
if (strcmp(s1, s2) == 0) |
strcpy(dst, src) with unknown input |
strncpy(dst, src, n - 1); dst[n-1] = '\0'; |
strcat without checking remaining space |
strncat(dst, src, sizeof(dst) - strlen(dst) - 1) |
gets(buf) — reads unlimited input |
fgets(buf, sizeof(buf), stdin) |
Modifying a string literal (char *s = "hello"; s[0] = 'H';) |
Use char s[] = "hello"; (array, not pointer) |
How to Compile
gcc -ansi -Wall -Wextra -o strings strings.c
All examples above compile clean with zero warnings under -ansi -Wall -Wextra.
Related C Programs
- Compare Two Strings in C — strcmp and manual
- Implement strlen from Scratch
- Concatenate Two Strings in C
- strstr Function Example
- strtok Function Example
- All C Programs
📖 For a deep dive into C strings and pointers together, see Chapter 5 of The C Programming Language by K&R (Amazon.in) · Amazon.com
Want to test your knowledge of C strings and more? Try the C Programming Quiz — 150+ questions including Arrays & Strings, free on Android.