C언어에서 strstr로 부분 문자열 찾는 법과 실전 예제

C언어에서 문자열 검색은 중요한 작업 중 하나이며, strstr 함수는 이를 간단히 처리할 수 있는 강력한 도구입니다. 이 함수는 특정 문자열 내에서 다른 문자열(부분 문자열)을 검색하여 첫 번째로 일치하는 위치를 반환합니다. 본 기사에서는 strstr 함수의 기본 사용법과 반환값의 의미, 실전 활용 예제를 통해 이 함수를 효과적으로 사용하는 방법을 알아봅니다.

`strstr` 함수란 무엇인가


C언어의 표준 라이브러리에 포함된 strstr 함수는 문자열에서 특정 부분 문자열을 찾는 데 사용됩니다. 이 함수는 <string.h> 헤더 파일에 선언되어 있으며, 다음과 같은 형식으로 정의됩니다:

char *strstr(const char *haystack, const char *needle);
  • haystack: 검색 대상이 되는 문자열입니다.
  • needle: 찾고자 하는 부분 문자열입니다.

동작 원리


strstr 함수는 haystack에서 needle과 일치하는 첫 번째 위치를 찾아 그 주소를 반환합니다. 만약 일치하는 부분 문자열이 없으면 NULL을 반환합니다.

예제

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "hello, world!";
    const char *search = "world";

    char *result = strstr(text, search);

    if (result) {
        printf("Found: %s\n", result);
    } else {
        printf("Not found.\n");
    }

    return 0;
}

출력:

Found: world!

이 예제에서는 text 문자열에서 “world”라는 부분 문자열을 찾아 그 위치를 출력합니다. strstr는 단순하면서도 강력한 기능을 제공해 문자열 검색 작업을 효율적으로 수행할 수 있습니다.

`strstr` 함수의 기본 사용법

strstr 함수는 간단한 문법과 직관적인 사용 방식으로 문자열 검색을 수행할 수 있습니다. 이 섹션에서는 strstr의 기본적인 사용법을 코드 예제와 함께 설명합니다.

기본 코드 구조


다음은 strstr 함수의 기본적인 사용 예제입니다:

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "The quick brown fox jumps over the lazy dog";
    const char *search = "fox";

    char *result = strstr(text, search);

    if (result) {
        printf("Substring found: %s\n", result);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

코드 설명

  • text: 검색 대상 문자열입니다.
  • search: 찾고자 하는 부분 문자열입니다.
  • result: strstr 함수가 반환하는 값으로, searchtext 내에서 처음 나타나는 위치를 가리키는 포인터입니다.

출력


위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다:

Substring found: fox jumps over the lazy dog

기본 사용법의 이해

  1. 성공적인 검색:
    strstr는 첫 번째로 일치하는 부분 문자열의 시작 주소를 반환합니다. 반환된 포인터는 부분 문자열을 포함한 남은 문자열을 나타냅니다.
  2. 검색 실패:
    만약 searchtext에 존재하지 않으면, strstrNULL을 반환합니다. 이를 통해 검색 결과를 조건문으로 처리할 수 있습니다.

이 기본 사용법을 통해 strstr 함수의 작동 방식을 이해하고 다양한 문자열 검색 작업에 적용할 수 있습니다.

반환값의 의미와 활용

strstr 함수의 반환값은 검색된 부분 문자열의 시작 주소를 나타내며, 이를 통해 다양한 방식으로 문자열을 처리할 수 있습니다. 이 섹션에서는 반환값의 의미를 설명하고, 이를 활용한 코드 작성 방법을 다룹니다.

반환값의 의미

  • 성공: 부분 문자열이 발견되면, 해당 부분 문자열의 시작 주소를 반환합니다. 반환값은 검색 대상 문자열의 포인터입니다.
  • 실패: 부분 문자열이 발견되지 않으면, NULL을 반환합니다.

활용 예제: 검색 결과 확인

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "Programming in C is fun!";
    const char *search = "C";

    char *result = strstr(text, search);

    if (result) {
        printf("Substring found at position: %ld\n", result - text);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

코드 설명

  • result - text: 반환된 포인터에서 검색 대상 문자열의 시작 주소를 빼면 부분 문자열의 위치(인덱스)를 계산할 수 있습니다.
  • NULL 확인: 반환값이 NULL인지 확인하여 검색 결과를 처리합니다.

출력

Substring found at position: 13

활용 예제: 반환값으로 후속 작업 수행


반환값을 사용하여 문자열을 처리할 수 있습니다. 예를 들어, 특정 부분 문자열 이후의 내용을 출력하거나 추가 작업을 수행할 수 있습니다.

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "Learn C programming at your own pace.";
    const char *search = "C";

    char *result = strstr(text, search);

    if (result) {
        printf("Remaining text: %s\n", result);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

출력

Remaining text: C programming at your own pace.

활용 팁

  • 반환값을 조건문에서 활용하여 문자열을 확인하거나 필요한 작업을 수행합니다.
  • 반환된 포인터를 이용해 문자열 조작, 잘라내기, 또는 특정 포지션에서 새로운 작업을 시작할 수 있습니다.

반환값의 의미를 잘 이해하고 이를 효과적으로 활용하면, 문자열 처리 작업을 더욱 유연하게 수행할 수 있습니다.

문자열이 존재하지 않을 경우 처리

strstr 함수는 검색 대상 문자열에서 찾고자 하는 부분 문자열이 없을 경우 NULL을 반환합니다. 이 반환값을 활용하여 적절한 예외 처리를 구현할 수 있습니다. 본 섹션에서는 검색 실패 상황에서 발생할 수 있는 문제와 이를 해결하기 위한 방법을 설명합니다.

검색 실패 처리 방법


검색 결과가 NULL인 경우를 처리하는 조건문을 작성하면, 프로그램의 안정성을 높일 수 있습니다.

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "Hello, world!";
    const char *search = "C";

    char *result = strstr(text, search);

    if (result) {
        printf("Substring found: %s\n", result);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

출력

Substring not found.

예외 처리의 중요성

  1. 프로그램 안정성 확보:
    NULL 반환값을 확인하지 않고 사용하면 런타임 에러가 발생할 수 있습니다.
  2. 사용자 피드백 제공:
    검색 실패 시 적절한 메시지를 제공함으로써 사용자에게 유용한 피드백을 전달할 수 있습니다.
  3. 후속 작업 방지:
    검색 실패 시 잘못된 데이터를 기반으로 후속 작업이 이루어지는 것을 방지합니다.

응용 예제: 사용자 입력 기반 검색


사용자로부터 검색 문자열을 입력받아 처리할 때도 검색 실패를 처리해야 합니다.

#include <stdio.h>
#include <string.h>

int main() {
    char text[100] = "This is an example text for strstr.";
    char search[50];

    printf("Enter a substring to search: ");
    scanf("%49s", search);

    char *result = strstr(text, search);

    if (result) {
        printf("Substring '%s' found at: %s\n", search, result);
    } else {
        printf("Substring '%s' not found in the text.\n", search);
    }

    return 0;
}

출력 예시


사용자가 text를 입력한 경우:

Enter a substring to search: text
Substring 'text' found at: text for strstr.

존재하지 않는 문자열을 입력한 경우:

Enter a substring to search: C++
Substring 'C++' not found in the text.

예외 처리 팁

  • 반환값이 NULL인 경우의 시나리오를 사전에 설계하여 프로그램이 중단되지 않도록 작성합니다.
  • 사용자에게 적절한 피드백을 제공하거나 기본 동작을 수행하도록 대체 옵션을 구현합니다.

검색 실패 상황에 대비한 처리를 통해 코드의 신뢰성과 안정성을 한층 강화할 수 있습니다.

`strstr`과 반복문을 활용한 다중 검색

strstr 함수는 문자열에서 첫 번째로 발견된 부분 문자열의 시작 위치를 반환합니다. 하지만 동일 문자열 내에서 여러 번 등장하는 부분 문자열을 찾으려면 반복문과 함께 사용해야 합니다. 이 섹션에서는 반복문과 strstr을 결합하여 다중 검색을 구현하는 방법을 설명합니다.

기본 원리


strstr을 사용해 문자열에서 첫 번째 위치를 찾은 뒤, 반환된 위치 이후로 다시 검색을 시작합니다. 이를 반복하여 모든 위치를 찾을 수 있습니다.

코드 예제


다음은 반복문을 활용한 다중 검색 구현 예제입니다:

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "The rain in Spain falls mainly in the plain.";
    const char *search = "in";

    const char *current_position = text;
    char *result;

    printf("Occurrences of '%s':\n", search);

    while ((result = strstr(current_position, search)) != NULL) {
        printf("Found at position: %ld\n", result - text);
        current_position = result + 1; // 다음 검색 위치로 이동
    }

    return 0;
}

코드 설명

  1. 초기화:
  • current_position은 검색 시작 위치를 나타냅니다. 처음에는 전체 문자열을 가리킵니다.
  1. 반복 검색:
  • strstr 반환값이 NULL이 될 때까지 반복합니다.
  1. 다음 위치로 이동:
  • 검색이 성공하면, 현재 위치 이후부터 다시 검색을 시작합니다.

출력

Occurrences of 'in':
Found at position: 5
Found at position: 12
Found at position: 27
Found at position: 43

응용: 문자열 강조


찾은 부분 문자열을 강조 표시하는 응용 예제입니다.

#include <stdio.h>
#include <string.h>

void highlight_substring(const char *text, const char *search) {
    const char *current_position = text;
    char *result;

    while ((result = strstr(current_position, search)) != NULL) {
        // 검색된 이전 부분 출력
        printf("%.*s", (int)(result - current_position), current_position);
        // 강조 표시
        printf("\033[1;31m%s\033[0m", search); // 빨간색 강조
        // 다음 검색 위치로 이동
        current_position = result + strlen(search);
    }
    // 남은 문자열 출력
    printf("%s\n", current_position);
}

int main() {
    const char *text = "The rain in Spain falls mainly in the plain.";
    const char *search = "in";

    printf("Original text:\n%s\n\n", text);
    printf("Highlighted text:\n");
    highlight_substring(text, search);

    return 0;
}

출력

Original text:
The rain in Spain falls mainly in the plain.

Highlighted text:
The ra\033[1;31min\033[0m Spa\033[1;31min\033[0m falls ma\033[1;31min\033[0mly \033[1;31min\033[0m the pla\033[1;31min\033[0m.

활용 팁

  • 반복문을 통해 모든 등장 위치를 찾고, 이를 기반으로 문자열을 수정하거나 분석할 수 있습니다.
  • 검색 결과를 배열이나 리스트에 저장하여 나중에 처리하거나 통계 정보를 생성할 수도 있습니다.

반복문과 strstr을 결합하면 문자열 검색 작업을 더욱 강력하게 수행할 수 있습니다.

`strstr`의 한계와 대안

strstr 함수는 간단한 문자열 검색에 유용하지만, 복잡한 문자열 처리나 대량의 데이터 검색에서 성능상의 한계가 있을 수 있습니다. 이 섹션에서는 strstr 함수의 한계를 분석하고, 더 나은 대안과 라이브러리를 소개합니다.

`strstr`의 한계

  1. 대소문자 구분:
    strstr 함수는 대소문자를 구분하여 검색합니다. 예를 들어, “Hello”와 “hello”는 다른 문자열로 인식됩니다.
  2. 부분 문자열의 모든 위치 검색:
    strstr은 첫 번째 발견된 부분 문자열만 반환합니다. 이를 해결하기 위해 반복문을 사용해야 하며, 코드가 복잡해질 수 있습니다.
  3. 멀티바이트 문자 지원 부족:
    멀티바이트 문자를 포함한 문자열(예: UTF-8 인코딩)에서의 검색 작업은 제한적입니다.
  4. 속도:
    문자열 검색 알고리즘이 간단하여 긴 문자열에서의 검색 성능이 낮을 수 있습니다.

대안 함수 및 기술

`strcasestr` (대소문자 구분 없음)


strcasestr 함수는 대소문자를 구분하지 않고 부분 문자열을 검색합니다. 이 함수는 GNU C 라이브러리에서 제공됩니다.

#include <stdio.h>
#include <string.h>

int main() {
    const char *text = "Hello, World!";
    const char *search = "world";

    char *result = strcasestr(text, search);

    if (result) {
        printf("Substring found: %s\n", result);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

고급 알고리즘 기반 검색

  1. Boyer-Moore 알고리즘:
    긴 문자열에서 효율적으로 검색할 수 있도록 최적화된 알고리즘입니다.
  2. Knuth-Morris-Pratt(KMP) 알고리즘:
    반복적인 문자열 검색에서 효율적으로 작동하며, 프리패턴 매칭 테이블을 사용합니다.

멀티바이트 문자열 검색: `wcsstr`


wcsstr 함수는 멀티바이트 문자를 지원하는 와이드 문자열 검색 함수입니다.

#include <wchar.h>
#include <wctype.h>
#include <stdio.h>

int main() {
    const wchar_t *text = L"안녕하세요, 세상!";
    const wchar_t *search = L"세상";

    wchar_t *result = wcsstr(text, search);

    if (result) {
        wprintf(L"Substring found: %ls\n", result);
    } else {
        wprintf(L"Substring not found.\n");
    }

    return 0;
}

외부 라이브러리 활용

  • PCRE (Perl Compatible Regular Expressions):
    정규식을 통해 복잡한 문자열 패턴 검색을 지원합니다.
  • Boost.Regex:
    C++에서 복잡한 문자열 검색을 수행할 수 있는 강력한 라이브러리입니다.

추천 사용 시나리오

  • 간단한 문자열 검색 작업: strstr 또는 strcasestr 사용.
  • 긴 문자열 데이터나 다중 검색: Boyer-Moore 또는 KMP 알고리즘 구현.
  • 멀티바이트 문자열 처리: wcsstr 사용.
  • 정교한 문자열 검색 및 매칭: 정규식 기반 라이브러리 활용.

결론


strstr 함수는 간단하고 직관적인 문자열 검색 도구로 유용하지만, 특정 상황에서는 한계가 분명합니다. 대안 함수나 고급 알고리즘을 사용하면 이러한 한계를 극복하고 효율적이고 확장 가능한 문자열 검색 작업을 수행할 수 있습니다.

응용 예제: 문자열 필터링

strstr 함수는 특정 조건에 따라 문자열을 필터링하는 데 활용될 수 있습니다. 이 섹션에서는 strstr을 사용하여 특정 키워드가 포함된 문자열만 추출하거나, 텍스트 데이터를 가공하는 방법을 살펴봅니다.

응용 1: 키워드 기반 필터링


다음은 주어진 문자열 배열에서 특정 키워드를 포함한 문자열만 출력하는 예제입니다.

#include <stdio.h>
#include <string.h>

int main() {
    const char *text_list[] = {
        "Learn C programming",
        "Master Python for data science",
        "Introduction to C++",
        "Data structures with C",
        "Web development with JavaScript"
    };

    const char *keyword = "C";

    printf("Lines containing '%s':\n", keyword);

    for (int i = 0; i < 5; i++) {
        if (strstr(text_list[i], keyword)) {
            printf("- %s\n", text_list[i]);
        }
    }

    return 0;
}

출력

Lines containing 'C':
- Learn C programming
- Introduction to C++
- Data structures with C

응용 2: 금지어 필터링


금지된 키워드가 포함된 문자열을 필터링하여 제외할 수도 있습니다.

#include <stdio.h>
#include <string.h>

int main() {
    const char *text_list[] = {
        "User posted spam content",
        "Valid user post",
        "Contains forbidden word",
        "Another normal post",
        "Spam detected"
    };

    const char *blacklist[] = { "spam", "forbidden" };

    printf("Approved posts:\n");

    for (int i = 0; i < 5; i++) {
        int is_blacklisted = 0;

        for (int j = 0; j < 2; j++) {
            if (strstr(text_list[i], blacklist[j])) {
                is_blacklisted = 1;
                break;
            }
        }

        if (!is_blacklisted) {
            printf("- %s\n", text_list[i]);
        }
    }

    return 0;
}

출력

Approved posts:
- Valid user post
- Another normal post

응용 3: 강조 표시


키워드가 포함된 부분을 강조 표시하여 시각적인 효과를 추가할 수도 있습니다.

#include <stdio.h>
#include <string.h>

void highlight_text(const char *text, const char *keyword) {
    const char *current_position = text;
    char *result;

    while ((result = strstr(current_position, keyword)) != NULL) {
        printf("%.*s", (int)(result - current_position), current_position); // 검색 전 텍스트
        printf("\033[1;31m%s\033[0m", keyword); // 강조 표시 (빨간색)
        current_position = result + strlen(keyword); // 다음 위치로 이동
    }

    printf("%s\n", current_position); // 남은 텍스트 출력
}

int main() {
    const char *text = "C is a powerful programming language. Many developers start with C.";
    const char *keyword = "C";

    printf("Original text:\n%s\n\n", text);
    printf("Highlighted text:\n");
    highlight_text(text, keyword);

    return 0;
}

출력

Original text:
C is a powerful programming language. Many developers start with C.

Highlighted text:
\033[1;31mC\033[0m is a powerful programming language. Many developers start with \033[1;31mC\033[0m.

활용 팁

  1. 데이터 필터링:
    로그 파일, 텍스트 데이터 등에서 특정 키워드가 포함된 라인만 선택적으로 추출할 때 유용합니다.
  2. 금지어 탐지:
    게시글이나 댓글에서 부적절한 단어를 필터링하거나 검출하는 데 활용할 수 있습니다.
  3. 검색 결과 표시:
    키워드를 강조 표시하여 검색 결과의 가독성을 높입니다.

strstr를 응용하면 데이터 필터링, 검출, 시각화 등 다양한 작업을 효과적으로 수행할 수 있습니다.

요약

strstr 함수는 C언어에서 문자열 내 부분 문자열을 검색하는 간단하면서도 강력한 도구입니다. 본 기사에서는 strstr의 기본 개념, 반환값의 활용, 반복문을 통한 다중 검색, 그리고 한계와 대안을 설명했습니다. 또한, 문자열 필터링과 강조 표시 같은 실전 응용 사례를 통해 함수의 활용 가능성을 보여주었습니다.

적절한 대안과 알고리즘을 이해하고 상황에 맞게 strstr을 활용하면, 문자열 처리 작업을 효율적이고 유연하게 수행할 수 있습니다.