A Comprehensive Guide
In C programming, a string is a sequence of characters terminated with a null character ('\0'). Strings are actually one-dimensional arrays of characters terminated by a null character. Thus, a null-terminated string contains the characters that comprise the string followed by a null.
Note: The null character ('\0') is important as it is the only way functions can know where the string ends.
char string_name[size];
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
// Or equivalently
char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str[6] = "Hello";
// Or with automatic size calculation
char str[] = "Hello";
char *str = "Hello"; // String literal stored in read-only memory
Warning: When using pointer initialization, the string is stored in read-only memory and cannot be modified. Attempting to modify it will result in undefined behavior.
Strings are stored as arrays of characters in contiguous memory locations, with the null terminator indicating the end of the string.
char str[] = "Hello";
| Index | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| Character | 'H' | 'e' | 'l' | 'l' | 'o' | '\0' |
| Address | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 |
Note: The null terminator ('\0') has an ASCII value of 0 and is automatically added by the compiler when using string literals.
char str[] = "Hello World";
printf("%s", str); // Output: Hello World
char str[] = "Hello World";
puts(str); // Output: Hello World (adds newline automatically)
char str[100];
printf("Enter a string: ");
scanf("%s", str); // Reads until whitespace
char str[100];
printf("Enter a string: ");
gets(str); // Reads until newline (potentially dangerous)
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin); // Safe input with size limit
Warning: Avoid using gets() as it doesn't check buffer boundaries and can lead to buffer overflow vulnerabilities. Always use fgets() instead.
C provides a rich set of string handling functions in the string.h header file.
| Function | Description | Example |
|---|---|---|
| strlen() | Returns the length of a string | strlen("Hello") returns 5 |
| strcpy() | Copies one string to another | strcpy(dest, src) |
| strncpy() | Copies up to n characters | strncpy(dest, src, n) |
| strcat() | Concatenates two strings | strcat(dest, src) |
| strncat() | Concatenates up to n characters | strncat(dest, src, n) |
| strcmp() | Compares two strings | strcmp(str1, str2) |
| strncmp() | Compares up to n characters | strncmp(str1, str2, n) |
| strchr() | Finds first occurrence of a character | strchr(str, 'a') |
| strstr() | Finds first occurrence of a substring | strstr(str, "abc") |
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
char str3[20];
// Get length
printf("Length of str1: %d\n", strlen(str1));
// Copy strings
strcpy(str3, str1);
printf("str3 after copy: %s\n", str3);
// Concatenate strings
strcat(str1, str2);
printf("str1 after concatenation: %s\n", str1);
// Compare strings
if (strcmp(str1, str2) == 0) {
printf("Strings are equal\n");
} else {
printf("Strings are not equal\n");
}
return 0;
}
int stringLength(const char *str) {
int length = 0;
while (str[length] != '\0') {
length++;
}
return length;
}
void stringCopy(char *dest, const char *src) {
int i = 0;
while (src[i] != '\0') {
dest[i] = src[i];
i++;
}
dest[i] = '\0';
}
void stringConcat(char *dest, const char *src) {
int dest_len = 0;
while (dest[dest_len] != '\0') {
dest_len++;
}
int i = 0;
while (src[i] != '\0') {
dest[dest_len + i] = src[i];
i++;
}
dest[dest_len + i] = '\0';
}
int stringCompare(const char *str1, const char *str2) {
int i = 0;
while (str1[i] != '\0' && str2[i] != '\0') {
if (str1[i] != str2[i]) {
return str1[i] - str2[i];
}
i++;
}
return str1[i] - str2[i];
}
void stringReverse(char *str) {
int length = 0;
while (str[length] != '\0') {
length++;
}
for (int i = 0; i < length / 2; i++) {
char temp = str[i];
str[i] = str[length - 1 - i];
str[length - 1 - i] = temp;
}
}
An array of strings is essentially a two-dimensional array of characters where each row represents a string.
char fruits[][10] = {
"Apple",
"Banana",
"Cherry",
"Date"
};
char *fruits[] = {
"Apple",
"Banana",
"Cherry",
"Date"
};
for (int i = 0; i < 4; i++) {
printf("Fruit %d: %s\n", i+1, fruits[i]);
}
#include <stdio.h>
#include <string.h>
void sortStrings(char arr[][10], int n) {
char temp[10];
for (int i = 0; i < n-1; i++) {
for (int j = i+1; j < n; j++) {
if (strcmp(arr[i], arr[j]) > 0) {
strcpy(temp, arr[i]);
strcpy(arr[i], arr[j]);
strcpy(arr[j], temp);
}
}
}
}
Strings can be dynamically allocated using memory allocation functions from stdlib.h.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *str;
int length;
printf("Enter maximum string length: ");
scanf("%d", &length);
// Allocate memory
str = (char *)malloc((length + 1) * sizeof(char));
if (str == NULL) {
printf("Memory allocation failed\n");
return 1;
}
printf("Enter a string: ");
scanf("%s", str);
printf("You entered: %s\n", str);
// Free allocated memory
free(str);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int numStrings;
printf("Enter number of strings: ");
scanf("%d", &numStrings);
// Allocate array of string pointers
char **strings = (char **)malloc(numStrings * sizeof(char *));
for (int i = 0; i < numStrings; i++) {
strings[i] = (char *)malloc(100 * sizeof(char));
printf("Enter string %d: ", i+1);
scanf("%s", strings[i]);
}
// Display strings
printf("\nYou entered:\n");
for (int i = 0; i < numStrings; i++) {
printf("%s\n", strings[i]);
}
// Free memory
for (int i = 0; i < numStrings; i++) {
free(strings[i]);
}
free(strings);
return 0;
}
Note: Always remember to free dynamically allocated memory to prevent memory leaks.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int isPalindrome(char *str) {
int left = 0;
int right = strlen(str) - 1;
while (left < right) {
// Ignore non-alphanumeric characters from left
while (!isalnum(str[left]) && left < right) left++;
// Ignore non-alphanumeric characters from right
while (!isalnum(str[right]) && left < right) right--;
// Compare characters (case insensitive)
if (tolower(str[left]) != tolower(str[right])) {
return 0; // Not a palindrome
}
left++;
right--;
}
return 1; // Is a palindrome
}
int main() {
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin);
// Remove newline character if present
if (str[strlen(str) - 1] == '\n') {
str[strlen(str) - 1] = '\0';
}
if (isPalindrome(str)) {
printf("'%s' is a palindrome.\n", str);
} else {
printf("'%s' is not a palindrome.\n", str);
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "This is a sample string";
char *token;
// Get the first token
token = strtok(str, " ");
// Walk through other tokens
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " ");
}
return 0;
}
This
is
a
sample
string
#include <stdio.h>
#include <ctype.h>
void encrypt(char *str, int shift) {
for (int i = 0; str[i] != '\0'; i++) {
if (isalpha(str[i])) {
char base = islower(str[i]) ? 'a' : 'A';
str[i] = (str[i] - base + shift) % 26 + base;
}
}
}
void decrypt(char *str, int shift) {
encrypt(str, 26 - (shift % 26));
}
int main() {
char str[100];
int shift;
printf("Enter a string to encrypt: ");
fgets(str, sizeof(str), stdin);
// Remove newline character if present
if (str[strlen(str) - 1] == '\n') {
str[strlen(str) - 1] = '\0';
}
printf("Enter shift value: ");
scanf("%d", &shift);
// Encrypt the string
encrypt(str, shift);
printf("Encrypted string: %s\n", str);
// Decrypt the string
decrypt(str, shift);
printf("Decrypted string: %s\n", str);
return 0;
}
Security Note: Many security vulnerabilities (like buffer overflow attacks) stem from improper string handling. Always validate input and check buffer sizes.