C Program to accept a string and a substring and check if the substring is present in the given string

Checking whether one string contains another is one of the most common string operations in C. The standard library provides strstr() in <string.h> — it returns a pointer to the first occurrence of the substring in the main string, or NULL if not found. The position of the match is calculated by subtracting the start pointer from the returned pointer.

The original post used conio.h, gets(), and void main(). It also implemented substring search manually using nested character comparison loops — correct in principle but unnecessary since strstr() does exactly this. This rewrite uses fgets() for safe input and strstr() for clean, proven searching.

C Program: Check if a Substring is Present in a String

/* Check if a substring is present in a string
 * Uses strstr() from <string.h>
 * Compile: gcc -ansi -Wall -Wextra substring.c -o substring */
#include <stdio.h>
#include <string.h>

int main(void)
{
    char str[256], sub[64];
    char *pos;

    printf("Enter main string: ");
    if (fgets(str, sizeof(str), stdin) == NULL) return 1;
    str[strcspn(str, "\n")] = '\0';  /* strip trailing newline */

    printf("Enter substring to search: ");
    if (fgets(sub, sizeof(sub), stdin) == NULL) return 1;
    sub[strcspn(sub, "\n")] = '\0';

    pos = strstr(str, sub);

    if (pos != NULL) {
        printf("Found \"%s\" in \"%s\" at position %d\n",
               sub, str, (int)(pos - str));
    } else {
        printf("\"%s\" not found in \"%s\"\n", sub, str);
    }
    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra substring.c -o substring
./substring

Sample Output

Enter main string: Hello, World!
Enter substring to search: World
Found "World" in "Hello, World!" at position 7

Enter main string: Hello, World!
Enter substring to search: Goodbye
"Goodbye" not found in "Hello, World!"

Enter main string: abcdefgh
Enter substring to search: abc
Found "abc" in "abcdefgh" at position 0

Enter main string: abcdefgh
Enter substring to search: fgh
Found "fgh" in "abcdefgh" at position 5

How strstr() Works

strstr(haystack, needle) searches for the first occurrence of needle in haystack. It returns a pointer to the start of the match, or NULL if the needle is not found.

Call Returns Position
strstr("Hello, World!", "World") pointer to ‘W’ 7
strstr("Hello, World!", "Goodbye") NULL not found
strstr("abcabc", "abc") pointer to first ‘a’ 0 (first occurrence)
strstr("abc", "") pointer to ‘a’ 0 (empty needle always matches)

Code Explanation

  • pos = strstr(str, sub) — returns a char * pointer into str at the start of the first match. If the substring appears multiple times, strstr only returns the first. To find all occurrences, call strstr again starting from pos + 1 in a loop.
  • (int)(pos - str) for position — since both pos and str are pointers into the same array, subtracting them gives the byte offset (0-based index) of the match. The cast to int is needed because pointer subtraction returns ptrdiff_t and %d expects int.
  • fgets() + strcspn() for inputfgets(str, sizeof(str), stdin) reads safely with a length limit. str[strcspn(str, "\n")] = '\0' removes the trailing newline that fgets includes. gets() in the original has no length limit and was removed from C11 due to buffer overflow risk.
  • Case sensitivitystrstr() is case-sensitive: “world” and “World” are different strings. For case-insensitive search, convert both strings to lowercase with tolower() in a loop before calling strstr, or use the POSIX function strcasestr() on Linux.

Finding All Occurrences

/* Find all occurrences of sub in str */
char *p = str;
int count = 0;
while ((p = strstr(p, sub)) != NULL) {
    printf("Found at position %d\n", (int)(p - str));
    p++;    /* advance past current match to find next */
    count++;
}
printf("Total: %d occurrence(s)\n", count);

What This Program Teaches

  • Pointer return values from string functions — strstr, strchr, and strrchr all return pointers into the original string. The pointer arithmetic pos - str recovers the 0-based index. This pattern appears throughout C string programming.
  • Always check for NULL before using a returned pointer — if strstr returns NULL and you attempt to dereference it (*pos or pos[0]), the program crashes with a segmentation fault. Always check if (pos != NULL) first.
  • fgets is the correct replacement for gets — never use gets(). fgets(buf, sizeof(buf), stdin) prevents buffer overflow by limiting input to sizeof(buf)-1 characters. The extra step of stripping the newline is a small price for safety.
  • strstr is O(n×m) in the worst case — n = length of haystack, m = length of needle. For extremely large strings or performance-critical code, algorithms like Knuth-Morris-Pratt or Boyer-Moore search in O(n+m). For typical string sizes in C programs, strstr is fast enough.

Related Programs

Recommended book:
The C Programming Language — Kernighan & Ritchie (India) |
(US)
 | 
C Programming: A Modern Approach — K.N. King (India) |
(US)

Practice what you learned: C Aptitude Questions — or try our C Programming Quiz App on Android.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>