What is the complete list and best practices for string handling functions in C language?
Core String Functions:
-
String Length
csize_t strlen(const char *str); // Returns string length, excluding null terminator '\0' -
String Copy
cchar *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n); // strncpy doesn't automatically add '\0', needs manual handling -
String Concatenation
cchar *strcat(char *dest, const char *src); char *strncat(char *dest, const char *src, size_t n); // Ensure destination buffer is large enough -
String Comparison
cint strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); // Return: 0 for equal, <0 if s1<s2, >0 if s1>s2 -
String Search
cchar *strchr(const char *str, int c); // Find first occurrence char *strrchr(const char *str, int c); // Find last occurrence char *strstr(const char *haystack, const char *needle); // Find substring -
String Tokenization
cchar *strtok(char *str, const char *delim); // Note: strtok modifies original string and is not thread-safe -
Secure Versions (C11)
cerrno_t strcpy_s(char *dest, rsize_t destsz, const char *src); errno_t strcat_s(char *dest, rsize_t destsz, const char *src);
Best Practices:
-
Buffer Overflow Protection
c// Unsafe strcpy(dest, src); // Safe approach strncpy(dest, src, sizeof(dest) - 1); dest[sizeof(dest) - 1] = '\0'; -
Safe String Concatenation
cchar buffer[100]; snprintf(buffer, sizeof(buffer), "%s%s", str1, str2); -
Dynamic String Handling
cchar *safe_strdup(const char *str) { if (!str) return NULL; size_t len = strlen(str) + 1; char *copy = malloc(len); if (copy) memcpy(copy, str, len); return copy; } -
String Formatting
cchar buffer[256]; int result = snprintf(buffer, sizeof(buffer), "Value: %d", value); if (result < 0 || result >= sizeof(buffer)) { // Handle error }
Common Pitfalls:
- Forgetting to reserve space for '\0'
- Using uninitialized strings
- Confusing strlen with sizeof
- Ignoring function return values
- State issues with multiple strtok calls