일상 메모장

strstr 사용법 및 구현 - C 문자열 처리 본문

C 언어

strstr 사용법 및 구현 - C 문자열 처리

핸드오버 2020. 1. 10. 10:18

설명

문자열에서 임의의 문자열의 시작하는 위치를 구하는 함수입니다. 

사용법

#include <string.h>

char *strstr(const char *haystack, const char *needle);

#define _GNU_SOURCE	/* See feature_test_macros(7) */

#include <string.h>

char *strcasestr(const char *haystack, const char *needle);

정의

문자열(haystack)에서 임의의 문자열(needle)을 찾으면 시작 위치의 포인터를 반환합니다.

'\0' NULL 바이트는 비교하지 않습니다.

비슷한 함수로는 strcasestr() 이 있는데 사용법은 같지만 이 함수는 대소문자를 구분하지 않습니다.

반환 값

임의의 문자열을 찾으면 임의의 문자열의 시작위치를 포인터로 반환합니다.

만약 문자열을 찾이 못하면 NULL을 반환합니다.

 

strstr 내부 구현 (strstr 실제 구현부)

/**
 * strstr - Find the first substring in a %NUL termicated string
 * @s1: The string to be searched
 * @s2: The string to search for
 */
char *strstr(const char *s1, const char s2)
{
	size_t l1, l2;

	l2 = strlen(s2);
    
	/* s2 문자열의 길이가 0이라면 무조건 매칭으로 보고 s1의 시작주소를 반환합니다. */
	if (!s2)
		return (char *)s1;

	l1 = strlen(s1);
	/* 남은 l1의 길이가 l2 길이 보다 작다면, 비교할 의미가 없으므로 NULL을 리턴합니다. */
	while (l1 >= l2) {
		l1--;
		/*
		 * s1의 포인터 위치를 이동하면서,
		 * 현재 s1과 s2의 메모리를 s2의 사이즈만큼 비교합니다.
		 * 같으면 현재 s1의 포인터를 리턴합니다.
		 */
		if (!memcmp(s1, s2, l2))
			return (char *)s1;
		s1++;
	}
	return NULL;
}

입력받은 문자열 s1 의 주소 값이 0x0000 이라고 가정하고 s1 문자열은 "abcdefg" s2 문자열은 "cde"라고 가정하겠습니다. 루프를 돌면서 s1의 주소를 한 칸식 이동하면서 s2 문자열과 memory 비교를 하게 됩니다.

(strlen 에 대해 궁금하시면 2020/01/08 - [C 언어] - strlen 사용법 및 구현 을 참고하시기 바랍니다.)

s1의 cde와 memcmp 가 같으면 현재 s1의 주소인 0x0002를 리턴하게 됩니다.

아래 표는 순차적으로 1~3번째 루프를 돌면서 매칭 되는 문자열을 찾는 모습입니다.

  0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007
s1 a b c d e f g '\0'
s2 c d e          
  0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007
s1 a b c d e f g '\0'
s2   c d e        
  0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007
s1 a b c d e f g '\0'
s2     c d e      

예제

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

int main()
{
	char s1[] = "abcdefg";
	char *ptr;

	/* s1 문자열 "abcdefg" 에서 "cde"문자열을 찾습니다. */
    ptr = strstr(s1, "cde");

	/*
	 * ptr에는 s1 문자열에서 문자 cde의 시작주소가 들어가있으므로,
	 * 출력값은 'c' 이후의 문자인 "cdefg" 가 출력됩니다.
	 */
	printf("%s\n", ptr);

	return 0;
}

결과값은 s1 문자열에서 'c' 의 포인터가 리턴되었으므로, "cdefg" 가 출력됩니다.