Finding the position of a substring means locating the index where one string first appears inside another — for example, “world” starts at index 6 in “hello world”. This is one of the most common string operations in C, used for parsing text, validating input, and implementing search features. The standard library already provides strstr() for this, but implementing it yourself is a classic exercise for understanding how string matching actually works under the hood.
This page covers a manual implementation using nested loops, a complete C program, sample runs, and how it compares to the built-in strstr() function.
How It Works — Step by Step
- Walk through the main string one character at a time, treating each position as a possible starting point for a match.
- At each starting position, compare characters one by one against the substring.
- If all characters match, that starting index is the answer.
- If any character differs, abandon this starting position and try the next one.
- If no starting position produces a full match, the substring isn’t present — return -1.
Step-by-step trace
Searching for "world" in "hello world":
Index 0: 'h' vs 'w' -> mismatch, try next index Index 1: 'e' vs 'w' -> mismatch ... Index 6: 'w','o','r','l','d' all match "world" -> found at index 6
C Program to Find the Position of a Substring
/* Find the Position of a Substring in C
* Compile: gcc -ansi -Wall -Wextra findsub.c -o findsub */
#include <stdio.h>
#include <string.h>
int find_substring(const char *str, const char *sub)
{
int i, j, str_len, sub_len;
str_len = (int)strlen(str);
sub_len = (int)strlen(sub);
if (sub_len == 0)
return 0;
for (i = 0; i <= str_len - sub_len; i++) {
for (j = 0; j < sub_len; j++) {
if (str[i + j] != sub[j])
break;
}
if (j == sub_len)
return i;
}
return -1;
}
int main(void)
{
char str[200], sub[100];
int pos;
printf("Enter the main string: ");
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0';
printf("Enter the substring to find: ");
fgets(sub, sizeof(sub), stdin);
sub[strcspn(sub, "\n")] = '\0';
pos = find_substring(str, sub);
if (pos == -1)
printf("\"%s\" not found in \"%s\"\n", sub, str);
else
printf("\"%s\" found at index %d in \"%s\"\n", sub, pos, str);
return 0;
}
How to Compile and Run
gcc -ansi -Wall -Wextra findsub.c -o findsub ./findsub
Sample Input and Output — Test 1 (found)
Enter the main string: hello world Enter the substring to find: world "world" found at index 6 in "hello world"
Sample Input and Output — Test 2 (not found)
Enter the main string: programming in c Enter the substring to find: xyz "xyz" not found in "programming in c"
Code Explanation
- Loop bound
i <= str_len - sub_len— there’s no point checking a starting index where the substring couldn’t possibly fit before the string ends. This also naturally handles the case where the substring is longer than the string (the loop simply never runs). - Inner loop with early
break— as soon as one character mismatches, there’s no need to keep comparing; abandoning early is what keeps this fast in practice even though its worst case is O(n·m). - fgets + strcspn instead of gets/scanf(“%s”) —
fgetsis bounds-safe and reads strings with spaces;strcspn(str, "\n")finds and strips the trailing newline thatfgetskeeps. - Empty substring edge case — an empty substring is considered to match at index 0, matching the behavior of the standard
strstr().
Time and Space Complexity
| Case | Time | Space |
|---|---|---|
| Worst case (many partial matches) | O(n × m) | O(1) extra |
| Typical case (few partial matches) | Close to O(n) | O(1) extra |
n = length of the main string, m = length of the substring. For guaranteed O(n + m) worst-case performance, algorithms like KMP (Knuth-Morris-Pratt) avoid re-checking characters already known to match — but for typical strings, this simple approach is more than fast enough.
What This Program Teaches
- Nested loop pattern-matching — the foundation every string-search algorithm builds on.
- Reading strings safely — using
fgets()with a bounded buffer instead of unsafe input functions. - Reimplementing a standard library function —
<string.h>already providesstrstr(str, sub), which does exactly this and should be preferred in real code; writing it yourself is what builds the understanding.
Related Programs
- Replace a Substring in C
- String Functions in C – Complete Reference
- Find String Length Without strlen()
- Palindrome String Check in C
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
Practice C string handling with the C Programming Quiz App — 500+ MCQs covering strings, pointers, sorting, and more.
Download on Google Play →