Progress: 11 of 16 topics68%

Strings in C Programming

Strings are sequences of characters used to represent text in programming. In C, unlike some higher-level languages, strings are not a built-in data type but rather implemented as arrays of characters. This tutorial will teach you how to create, manipulate, and effectively work with strings in C programming.

What You'll Learn

  • How strings are represented in C
  • String declaration and initialization
  • String input and output operations
  • String manipulation functions
  • String comparison techniques
  • Common string operations
  • Memory management with strings
  • Best practices and common pitfalls

String Representation in C

In C, strings are represented as arrays of characters terminated by a special character called the null character ('\0'). This null character marks the end of the string and is crucial for many string functions to work properly.

String Representation

H
e
l
l
o
\0
index 0
index 1
index 2
index 3
index 4
index 5

String: "Hello"

Length: 5 characters

Size in memory: 6 bytes (5 characters + null terminator)

Key Points About Strings in C

  • Strings are character arrays terminated by the null character '\0'
  • The null terminator is automatically added when initializing with string literals
  • The array size must be at least one more than the string length to accommodate the null terminator
  • Without the null terminator, many string functions won't work correctly

String Declaration and Initialization

There are several ways to declare and initialize strings in C:

c
1// Method 1: Character by character (with explicit null terminator)
2char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
3
4// Method 2: Using string literal (null terminator added automatically)
5char message[] = "Hello";
6
7// Method 3: Declare then initialize (not recommended for strings)
8char name[10];
9name[0] = 'J'; name[1] = 'o'; name[2] = 'h'; name[3] = 'n'; name[4] = '\0';
10
11// Method 4: Fixed-size array (be careful of size!)
12char country[20] = "USA";
13
14// Method 5: Using pointers (string literals are stored in read-only memory)
15const char *title = "CEO"; // Use const to avoid compiler warnings

Important Considerations

Array Size

Always allocate enough space for the entire string plus the null terminator. For example, to store "Hello" (5 characters), you need an array of at least 6 bytes.

String Literals

String literals like "Hello" are stored in read-only memory. If you use a pointer to a string literal, don't attempt to modify it.

String Input and Output

C provides several functions for reading and printing strings.

Printing Strings

c
1#include <stdio.h>
2
3int main() {
4 char greeting[] = "Hello, World!";
5
6 // Method 1: Using printf with %s format specifier
7 printf("%s\n", greeting);
8
9 // Method 2: Using puts (automatically adds a newline)
10 puts(greeting);
11
12 // Method 3: Print character by character
13 for (int i = 0; greeting[i] != '\0'; i++) {
14 putchar(greeting[i]);
15 }
16 putchar('\n');
17
18 return 0;
19}
20
21// Output:
22// Hello, World!
23// Hello, World!
24// Hello, World!

Reading Strings

c
1#include <stdio.h>
2
3int main() {
4 char name[50];
5 char description[100];
6
7 // Method 1: Using scanf (stops at whitespace)
8 printf("Enter your name: ");
9 scanf("%s", name); // Warning: No bounds checking!
10 printf("Hello, %s!\n", name);
11
12 // Clear input buffer
13 while (getchar() != '\n');
14
15 // Method 2: Using fgets (safer, reads entire line including spaces)
16 printf("Describe yourself: ");
17 fgets(description, sizeof(description), stdin);
18 printf("Description: %s", description); // fgets keeps the newline character
19
20 return 0;
21}
22
23// Example interaction:
24// Enter your name: John
25// Hello, John!
26// Describe yourself: I am a programmer
27// Description: I am a programmer

Warning About scanf()

Using scanf("%s", str) is dangerous because it doesn't perform bounds checking and can lead to buffer overflow if the input is longer than the array. Prefer fgets() or use scanf("%49s", str) to limit input length.

String Library Functions

The C standard library provides many useful functions for working with strings in the <string.h> header. Here are some of the most commonly used ones:

String Length: strlen()

c
1#include <stdio.h>
2#include <string.h>
3
4int main() {
5 char text[] = "Hello, C Programming!";
6
7 // Get the length of a string (excludes the null terminator)
8 size_t length = strlen(text);
9
10 printf("The string: "%s"\n", text);
11 printf("Length: %zu characters\n", length);
12
13 return 0;
14}
15
16// Output:
17// The string: "Hello, C Programming!"
18// Length: 22 characters

String Copy: strcpy() and strncpy()

c
1#include <stdio.h>
2#include <string.h>
3
4int main() {
5 char source[] = "Hello, world!";
6 char destination1[20];
7 char destination2[10];
8
9 // Copy entire string (unsafe if destination is smaller than source)
10 strcpy(destination1, source);
11 printf("strcpy result: %s\n", destination1);
12
13 // Copy with length limit (safer)
14 strncpy(destination2, source, sizeof(destination2) - 1);
15 destination2[sizeof(destination2) - 1] = '\0'; // Ensure null termination
16 printf("strncpy result: %s\n", destination2);
17
18 return 0;
19}
20
21// Output:
22// strcpy result: Hello, world!
23// strncpy result: Hello, wo

String Concatenation: strcat() and strncat()

c
1#include <stdio.h>
2#include <string.h>
3
4int main() {
5 char result[50] = "Hello, ";
6 char name[] = "C Programmer!";
7
8 // Append one string to another (unsafe without size check)
9 strcat(result, name);
10 printf("strcat result: %s\n", result);
11
12 // Reset the result string
13 strcpy(result, "Hello, ");
14
15 // Append with length limit (safer)
16 strncat(result, name, 5); // Append only 5 characters
17 printf("strncat result: %s\n", result);
18
19 return 0;
20}
21
22// Output:
23// strcat result: Hello, C Programmer!
24// strncat result: Hello, C Pro

String Comparison: strcmp() and strncmp()

c
1#include <stdio.h>
2#include <string.h>
3
4int main() {
5 char string1[] = "apple";
6 char string2[] = "banana";
7 char string3[] = "apple";
8
9 // Compare two strings
10 int result1 = strcmp(string1, string2);
11 int result2 = strcmp(string1, string3);
12 int result3 = strcmp(string2, string1);
13
14 printf("strcmp(apple, banana): %d\n", result1); // Negative (a comes before b)
15 printf("strcmp(apple, apple): %d\n", result2); // Zero (identical strings)
16 printf("strcmp(banana, apple): %d\n", result3); // Positive (b comes after a)
17
18 // Compare with length limit
19 char prefix[] = "app";
20 int result4 = strncmp(string1, prefix, strlen(prefix));
21 printf("strncmp(apple, app, 3): %d\n", result4); // Zero (prefix matches)
22
23 return 0;
24}
25
26// Output:
27// strcmp(apple, banana): -1
28// strcmp(apple, apple): 0
29// strcmp(banana, apple): 1
30// strncmp(apple, app, 3): 0

Understanding strcmp() Return Values

  • Negative value: The first string comes before the second in lexicographical order
  • Zero: The strings are identical
  • Positive value: The first string comes after the second in lexicographical order

Note: The exact values (-1, 0, 1) may vary across different implementations; only rely on the sign.

Searching in Strings: strchr() and strstr()

c
1#include <stdio.h>
2#include <string.h>
3
4int main() {
5 char text[] = "The quick brown fox jumps over the lazy dog";
6
7 // Find first occurrence of a character
8 char *result1 = strchr(text, 'q');
9 if (result1 != NULL) {
10 printf("First 'q' found at position: %ld\n", result1 - text);
11 printf("Substring from 'q': %s\n", result1);
12 }
13
14 // Find first occurrence of a substring
15 char *result2 = strstr(text, "fox");
16 if (result2 != NULL) {
17 printf("Substring "fox" found at position: %ld\n", result2 - text);
18 printf("Substring from "fox": %s\n", result2);
19 }
20
21 return 0;
22}
23
24// Output:
25// First 'q' found at position: 4
26// Substring from 'q': quick brown fox jumps over the lazy dog
27// Substring "fox" found at position: 16
28// Substring from "fox": fox jumps over the lazy dog

Converting Strings: atoi(), atof(), etc.

c
1#include <stdio.h>
2#include <stdlib.h> // For string conversion functions
3
4int main() {
5 char num_str1[] = "42";
6 char num_str2[] = "3.14159";
7 char num_str3[] = "123abc"; // Only the numeric part will be converted
8
9 // Convert string to integer
10 int num1 = atoi(num_str1);
11 printf(""%s" as integer: %d\n", num_str1, num1);
12
13 // Convert string to float
14 float num2 = atof(num_str2);
15 printf(""%s" as float: %f\n", num_str2, num2);
16
17 // Only the numeric part is converted
18 int num3 = atoi(num_str3);
19 printf(""%s" as integer: %d\n", num_str3, num3);
20
21 return 0;
22}
23
24// Output:
25// "42" as integer: 42
26// "3.14159" as float: 3.141590
27// "123abc" as integer: 123

String Manipulation Examples

Reversing a String

c
1#include <stdio.h>
2#include <string.h>
3
4void reverseString(char str[]) {
5 int length = strlen(str);
6 int i, j;
7 char temp;
8
9 for (i = 0, j = length - 1; i < j; i++, j--) {
10 temp = str[i];
11 str[i] = str[j];
12 str[j] = temp;
13 }
14}
15
16int main() {
17 char text[] = "Hello, World!";
18
19 printf("Original string: %s\n", text);
20
21 reverseString(text);
22
23 printf("Reversed string: %s\n", text);
24
25 return 0;
26}
27
28// Output:
29// Original string: Hello, World!
30// Reversed string: !dlroW ,olleH

Converting Case

c
1#include <stdio.h>
2#include <ctype.h> // For character handling functions
3
4void convertToUppercase(char str[]) {
5 for (int i = 0; str[i] != '\0'; i++) {
6 str[i] = toupper(str[i]);
7 }
8}
9
10void convertToLowercase(char str[]) {
11 for (int i = 0; str[i] != '\0'; i++) {
12 str[i] = tolower(str[i]);
13 }
14}
15
16int main() {
17 char text1[] = "Hello, World!";
18 char text2[] = "Hello, World!";
19
20 printf("Original string: %s\n", text1);
21
22 convertToUppercase(text1);
23 printf("Uppercase: %s\n", text1);
24
25 convertToLowercase(text2);
26 printf("Lowercase: %s\n", text2);
27
28 return 0;
29}
30
31// Output:
32// Original string: Hello, World!
33// Uppercase: HELLO, WORLD!
34// Lowercase: hello, world!

Dynamic Memory Allocation for Strings

For strings of unknown or variable size, you can use dynamic memory allocation to create strings at runtime.

c
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5int main() {
6 // Allocate memory for a string
7 char *dynamic_str = (char *)malloc(50 * sizeof(char));
8
9 if (dynamic_str == NULL) {
10 printf("Memory allocation failed!\n");
11 return 1;
12 }
13
14 // Copy a string to the allocated memory
15 strcpy(dynamic_str, "This is a dynamically allocated string");
16
17 printf("%s\n", dynamic_str);
18
19 // Resize the string
20 char *resized_str = (char *)realloc(dynamic_str, 100 * sizeof(char));
21
22 if (resized_str == NULL) {
23 printf("Memory reallocation failed!\n");
24 free(dynamic_str); // Free the original memory if reallocation fails
25 return 1;
26 }
27
28 dynamic_str = resized_str; // Update the pointer
29
30 // Append to the resized string
31 strcat(dynamic_str, " that has been resized to fit more text");
32
33 printf("%s\n", dynamic_str);
34
35 // Don't forget to free the memory when done
36 free(dynamic_str);
37
38 return 0;
39}
40
41// Output:
42// This is a dynamically allocated string
43// This is a dynamically allocated string that has been resized to fit more text

Important Memory Management Rules

  • Always check if memory allocation was successful before using the pointer
  • Always free dynamically allocated memory when it's no longer needed
  • Be careful not to use memory after it's been freed (dangling pointer)
  • Don't forget to allocate space for the null terminator when allocating memory for strings

Common Pitfalls and Best Practices

Buffer Overflow

Writing more characters than the allocated space can overwrite adjacent memory, causing crashes or security vulnerabilities.

Avoid by:

  • Always check string lengths before copying
  • Use safer functions like strncpy(), strncat() with proper size limits
  • Allocate sufficient memory for strings plus the null terminator

Missing Null Terminator

Without a null terminator, string functions will keep reading memory until they find a null byte, potentially causing crashes.

Avoid by:

  • Always ensure strings are properly null-terminated
  • When using strncpy(), manually add the null terminator if needed
  • Initialize character arrays with zeros when appropriate

Best Practices for String Handling

  • Always allocate enough memory for your strings (including the null terminator)
  • Use bounds-checking functions (strncpy, strncat) instead of their unsafe counterparts
  • Check return values from string functions for error conditions
  • Be careful with user input - always validate and limit input length
  • Free dynamically allocated memory when it's no longer needed
  • Consider using string libraries for complex string manipulation

Practice Exercises

🎯 Try these exercises:

  1. Write a function to count the number of words in a string.
  2. Create a program to check if a string is a palindrome (reads the same forwards and backwards).
  3. Implement a function that removes all spaces from a string.
  4. Write a program to find the first non-repeating character in a string.
  5. Create a function that capitalizes the first letter of each word in a sentence.

Summary

In this tutorial, you've learned about strings in C programming:

  • Strings in C are arrays of characters terminated by the null character ('\0')
  • There are multiple ways to declare and initialize strings
  • The C standard library provides many functions for string manipulation in <string.h>
  • Common string operations include finding length, copying, concatenating, and comparing
  • Dynamic memory allocation allows for flexible string handling
  • Proper memory management and bounds checking are essential for safe string handling
  • Using safer string functions helps prevent buffer overflows and other security issues

Mastering string manipulation is crucial for C programming, as text processing is a common task in many applications. With the knowledge from this tutorial, you'll be able to handle text data effectively and safely in your C programs.

Related Tutorials

Arrays in C

Learn about working with collections of data in C programming.

Continue learning

Pointers in C

Master pointers, a powerful feature in C programming.

Continue learning

File I/O in C

Understand how to work with files for data persistence.

Continue learning