Skip to main content

C String Functions: Mastering string.h 🧰

Mentor's Note: Think of the <string.h> library like a Swiss Army knife. Instead of whittling raw wood or cutting string with your bare hands using custom loops, these built-in functions let you manipulate text safely and efficiently in a single line! 💡

📚 Educational Content: In GSEB Std 11/12, CBSE Class 11/12, and BCA Semester 1 examinations, string manipulation is a staple topic. Questions often focus on the difference between safe and unsafe functions (like strcpy vs strncpy) and tracing code that uses strtok or strcmp.

What You'll Learn

By the end of this tutorial, you'll know:

  • How to include and utilize the <string.h> header file.
  • The syntax, parameters, and behavior of 11 essential string functions.
  • The critical security difference between strcpy and strncpy.
  • How to split text into tokens using strtok and write formatted data with sprintf.
  • The common traps like buffer overflows and missing null-terminators.

🌟 The Scenario: The Post Office Label Machine

Imagine you work in a high-speed post office sorting and labeling packages:

  • strlen is the scale. It measures the weight (number of letters) of a word label, but ignores the box itself.
  • strcpy is a photocopier. It takes the text from one label and copies it onto a blank label. If the blank label is too small, the ink spills over the edges and ruins the office desk (buffer overflow!).
  • strcat is glue. It takes one label and sticks it directly onto the end of another.
  • strcmp is the inspector. It compares two address labels side-by-side to check if they are identical or which one comes first in the alphabetical directory.

📖 Concept Explanation

Because C does not have a native "String" class, all text operations are performed on character arrays. To make this easier, the C Standard Library provides the <string.h> header, which contains functions designed to manipulate null-terminated character arrays.

String Functions Reference Table

FunctionHeaderSyntaxReturn TypeDescription
strlen<string.h>strlen(const char *str)size_tReturns the length of str (excluding the null terminator \0).
strcpy<string.h>strcpy(char *dest, const char *src)char *Copies src to dest (Unsafe: does not check buffer limits).
strncpy<string.h>strncpy(char *dest, const char *src, size_t n)char *Copies up to n characters from src to dest.
strcmp<string.h>strcmp(const char *s1, const char *s2)intCompares s1 and s2 lexicographically.
strncmp<string.h>strncmp(const char *s1, const char *s2, size_t n)intCompares the first n characters of s1 and s2.
strcat<string.h>strcat(char *dest, const char *src)char *Appends src to the end of dest (Unsafe).
strncat<string.h>strncat(char *dest, const char *src, size_t n)char *Appends up to n characters from src to dest.
strchr<string.h>strchr(const char *str, int ch)char *Returns a pointer to the first occurrence of character ch in str.
strstr<string.h>strstr(const char *haystack, const char *needle)char *Returns a pointer to the first occurrence of substring needle in haystack.
strtok<string.h>strtok(char *str, const char *delim)char *Splits str into tokens using delimiters.
sprintf<stdio.h>sprintf(char *buf, const char *format, ...)intWrites formatted output into the character buffer buf.

🔒 Security Showdown: strcpy vs strncpy

Understanding buffer overflows is essential for writing secure code.

Unsafe copy: strcpy

When you execute strcpy(dest, src), C copies characters from src to dest one-by-one until it detects the null terminator \0. If src has 20 characters and dest is only allocated 10 bytes of memory, strcpy will blindly write the remaining 10 characters into adjacent memory locations. This corrupts nearby variables and causes crashes or security exploits.

Safe copy: strncpy

To prevent this, you should use strncpy(dest, src, n), where n is the maximum capacity of dest.

Critical Gotcha with strncpy

If the length of src is equal to or greater than n, strncpy will copy the first n characters but will not append the null terminator (\0). If you print dest later, printf will read past the array boundary trying to find \0, resulting in garbage printouts or crashes. Always manually terminate the string after calling strncpy!

strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // Manual termination guaranteed

🧠 Algorithm & Step-by-Step Logic

Let's review the step-by-step logic of tokenizing a comma-separated string (like "Mango,Orange,Banana") using strtok:

  1. Start 🏁
  2. First Call: Pass the string and delimiter to strtok(str, ",").
    • strtok finds the first comma, replaces it with \0, and returns a pointer to the start of "Mango".
  3. Subsequent Calls: Call strtok(NULL, ",").
    • By passing NULL as the first argument, you instruct strtok to continue from where it left off.
    • It replaces the next comma with \0 and returns a pointer to "Orange".
  4. End Condition: Repeat step 3 until strtok returns NULL, indicating no more tokens are left.
  5. End 🏁

💻 Implementation (C99)

The following program demonstrates all key string functions, highlighting the difference between safe and unsafe copying, string searching, and tokenization.

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

// 🛒 Scenario: Office String Processor
// 🚀 Action: Showcase safety checks, concatenation, comparisons, tokenization, and formatting

int main() {
// 1. Measuring Length vs Size
char word[10] = "Apple";
printf("1. Length of '%s': %zu\n", word, strlen(word));
printf(" Memory Size of '%s': %zu bytes\n\n", word, sizeof(word));

// 2. Unsafe vs Safe String Copying
char src[] = "SuperLongMessageThatCanOverflow";
char safe_dest[15];

// Safe copying using strncpy with manual termination
strncpy(safe_dest, src, sizeof(safe_dest) - 1);
safe_dest[sizeof(safe_dest) - 1] = '\0';
printf("2. Safe Copy Result: %s\n\n", safe_dest);

// 3. String Comparison
char pass1[] = "Surat2026";
char pass2[] = "Surat2026";
char pass3[] = "surat2026"; // uppercase difference

if (strcmp(pass1, pass2) == 0) {
printf("3. pass1 and pass2 are identical.\n");
}
if (strcmp(pass1, pass3) != 0) {
printf(" pass1 and pass3 are different (case-sensitive).\n\n");
}

// 4. Safe Concatenation
char greeting[30] = "Welcome, ";
char user[] = "Vishnu Damwala!";
strncat(greeting, user, sizeof(greeting) - strlen(greeting) - 1);
printf("4. Concatenation: %s\n\n", greeting);

// 5. Searching for Characters and Substrings
char email[] = "[email protected]";
char *domain = strchr(email, '@');
if (domain != NULL) {
printf("5. Domain found starting from: %s\n", domain);
}

char sentence[] = "Learning C programming is fun!";
char *match = strstr(sentence, "programming");
if (match != NULL) {
printf(" Substring found: %s\n\n", match);
}

// 6. Tokenization
char csv_data[] = "Physics,Chemistry,Maths";
printf("6. Tokenizing '%s':\n", csv_data);
char *token = strtok(csv_data, ",");
while (token != NULL) {
printf(" - Token: %s\n", token);
token = strtok(NULL, ","); // Notice NULL is passed to continue
}
printf("\n");

// 7. Writing Formatted Output to a String
char report_buffer[60];
int roll_no = 42;
float gpa = 9.8;
sprintf(report_buffer, "Student Info -> Roll: %d, GPA: %.2f", roll_no, gpa);
printf("7. Formatted String: %s\n", report_buffer);

return 0;
}

// Output:
// 1. Length of 'Apple': 5
// Memory Size of 'Apple': 10 bytes
//
// 2. Safe Copy Result: SuperLongMessa
//
// 3. pass1 and pass2 are identical.
// pass1 and pass3 are different (case-sensitive).
//
// 4. Concatenation: Welcome, Vishnu Damwala!
//
// 5. Domain found starting from: @vishnudigital.com
// Substring found: programming is fun!
//
// 6. Tokenizing 'Physics,Chemistry,Maths':
// - Token: Physics
// - Token: Chemistry
// - Token: Maths
//
// 7. Formatted String: Student Info -> Roll: 42, GPA: 9.80

📊 Sample Dry Run

Let's trace how the memory changes when strtok processes the string "A,B" with delimiter ",". Assume csv is stored at memory address 1000.

StepFunction CallPointer ReturnedString state in memoryDescription
1strtok(csv, ",")Pointer to 1000 ("A")'A' '\0' 'B' '\0'strtok finds the comma at index 1, replaces it with \0, and returns start address.
2strtok(NULL, ",")Pointer to 1002 ("B")'A' '\0' 'B' '\0'strtok resumes from index 2, reads until end of string, and returns address 1002.
3strtok(NULL, ",")NULL'A' '\0' 'B' '\0'No more delimiters or characters. Loop terminates.

📉 Complexity Analysis

Time Complexity ⏱️

  • strlen: $O(N)$ because it must iterate through the string character-by-character to find the null terminator.
  • strcpy / strncpy: $O(N)$ where $N$ is the number of characters copied.
  • strcmp: $O(N)$ in the worst case, as it compares characters one-by-one until a mismatch or \0 is found.
  • strstr: $O(N \times M)$ where $N$ is the length of the string and $M$ is the length of the substring (using standard naive algorithm).

Space Complexity 💾

  • Auxiliary Space: $O(1)$ because all of these functions modify strings in-place or traverse them using pointers, without allocating extra heap memory.

🎨 Visual Logic & Diagrams

The diagram below illustrates how strtok replaces delimiters in memory dynamically:


🎯 Practice Problems

Easy Level 🟢

  • Problem 1: Write a program to read a user's full name and count the total number of characters, excluding spaces.
  • Problem 2: Implement a basic password matcher using strcmp.

Medium Level 🟡

  • Problem 3: Write a custom version of strncat without using <string.h> library functions.
  • Problem 4: Read a string containing a path (e.g., "/usr/bin/gcc") and extract the file name ("gcc") using strrchr.

Hard Level 🔴

  • Problem 5: Write a secure parser that reads a sentence from the user, splits it into words using spaces as delimiters, and builds a reverse sentence using sprintf to output the results safely.

❓ Frequently Asked Questions

Details

Q: What is the difference between sizeof() and strlen() for a string? sizeof() is a compile-time operator that returns the total size allocated for the array in memory, including unused space and the null terminator. strlen() is a runtime function that counts only the active characters up to (but not including) the null terminator \0.

Details

Q: Why does my program crash when using strtok on a string literal? strtok modifies the string in-place by writing null characters (\0) into it. String literals (e.g., char *str = "Hello,World";) are stored in read-only memory. Attempting to modify them results in a Segmentation Fault. You must copy the literal into a character array first (e.g., char str[] = "Hello,World";).

Details

Q: Why does strcmp return non-boolean values like -1 or 2 instead of just 0 or 1? strcmp returns the subtraction result of the first mismatched character's ASCII value. If s1 is smaller than s2, it returns a negative value. If s1 is larger, it returns a positive value. This behavior is useful for sorting strings alphabetically.


✅ Summary

In this tutorial, you've learned:

  • <string.h> is the essential header containing helpers for character arrays.
  • strncpy and strncat are the secure, length-bounded versions of strcpy and strcat.
  • Manual null termination is mandatory when strncpy truncates a source string.
  • strtok splits strings destructively by inserting \0 characters in-place.
  • sprintf formats non-string data types directly into a text buffer.

💡 Interview Tips & Board Focus 👔

Common Questions

  • "Why is strcpy dangerous, and how does strncpy solve its issues?"
  • "What does strcmp return when two strings are compared?"
  • "Write your own version of strlen without using <string.h>."

Answering Strategy

  • When asked to write custom string functions in board exams, remember to write a loop that runs until it hits the null terminator character: while(str[i] != '\0').
  • Mention that strncpy is preferred in production-grade software to prevent buffer-overflow vulnerabilities.

📚 Best Practices & Common Mistakes

✅ Best Practices

  • Always define destination arrays with enough size to hold the text and the null character \0.
  • Use the length-safe strn... variants of string functions.
  • Set the last character of a destination buffer to \0 after strncpy.

❌ Common Mistakes ⚠️

  • Forgetting that strtok modifies the input array. If you need the original string later, copy it first.
  • Accessing return pointers of strstr or strchr without checking if they are NULL (causes runtime crashes).
  • Writing char dest[5]; strcpy(dest, "Surat"); — the string "Surat" requires 6 bytes (including \0), so this overflows the buffer.

📚 Further Reading

Continue your learning path:


Guide Version: 2.0
Purpose: Educational content creation standards for VD Computer Tuition


---

📍 Visit Us

🏫 VD Computer Tuition Surat

VD Computer Tuition
📍 Address
2/66 Faram Street, Rustompura
Surat395002, Gujarat, India
📞 Phone / WhatsApp
+91 84604 41384
🌐 Website

Computer Classes & Tuition — Areas We Serve in Surat

AdajanAlthanAmroliAthwaAthwalinesBhagalBhatarBhestanCanal RoadChowkCitylightDumasGaurav PathGhod Dod RoadHaziraJahangirpuraKamrejKapodraKatargamLimbayatMagdallaMajura GateMota VarachhaNanpuraNew CitylightOlpadPalPandesaraParle PointPiplodPunaRanderRing RoadRustampuraSachinSalabatpuraSarthanaSosyo CircleUdhnaVarachhaVed RoadVesuVIP Road
📞 Call Sir💬 WhatsApp Sir