jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. strtok_r
    1. 알아보기
      1. 기본형
      2. 인자 보기
      3. 동작 흐름

TIL을 하루에 5개 올리는 정도의 능력


지령전을 360도 바꿀 능력이다


strtok_r

char *
strtok_r (char *s, const char *delimiters, char **save_ptr) {
	char *token;

	ASSERT (delimiters != NULL);
	ASSERT (save_ptr != NULL);

	/* S가 NULL이 아니면 그 지점부터 시작합니다.
	   S가 NULL이면 저장된 위치에서 시작합니다. */
	if (s == NULL)
		s = *save_ptr;
	ASSERT (s != NULL);

	/* 현재 위치에서 구분자(DELIMITERS)를 건너뜁니다. */
	while (strchr (delimiters, *s) != NULL) {
		/* 찾는 문자가 널 바이트인 경우, 모든 문자열은 (끝에) 널 바이트를
		   포함하므로 strchr()는 항상 NULL이 아닌 값을 반환합니다. */
		if (*s == '\0') {
			*save_ptr = s;
			return NULL;
		}

		s++;
	}

	/* 문자열 끝(또는 구분자)을 만날 때까지 구분자가 아닌 문자들을 건너뜁니다. */
	token = s;
	while (strchr (delimiters, *s) == NULL)
		s++;
	if (*s != '\0') {
		*s = '\0';
		*save_ptr = s + 1;
	} else
		*save_ptr = s;
	return token;
}

인자 문자열 쪼개는 함수다

인자 전달 Argument Passing에 나오는
lib/string.c에 주석이 풍부하게 구현된 strtok_r()이다

뭐하는 역할이기에 그렇게 보라고 했는지 알아보자


알아보기

기본형

char *strtok_r(char *s, const char *delims, char **save_ptr)


인자 보기

  • s
    첫 호출시에는 쓰기 가능한(NUL로 끊어낼 수 있는) C문자열의 시작주소
    이후 호출에서는 NULL을 넣어 이전 위치부터 계속
    • 읽기 전용 메모리 사수를 위해 중간에 '\0'으로 끊는다
  • delims
    구분자 문자들의 집합 (예:\t\n)
    NULL 금지

  • save_ptr
    내부 진행 상태 저장할 포인터 변수 주소, NULL 금지
    첫 호출 전에 *save_ptr은 무시해준다 s가 있으니

동작 흐름

  1. 시작 위치 결정

    • s != NULL이면 거기서 시작

    • s == NULL이면 이전에 저장해둔 *save_ptr에서 재개

  2. 선행 구분자 스킵

    • 현재 문자가 구분자 집합에 속하면 계속 한 칸씩 전진

    • 이 과정에서 입력 문자열 끝('\0')을 만나면 *save_ptr = s로 맞춰두고 NULL 반환(토큰 없음)

  3. 토큰 시작 표시

    • 현 위치를 token = s로 기억(여기가 토큰의 첫 글자)
  4. 토큰 본문 통과

    • 구분자를 만날 때까지 전진. 구분자나 '\0'를 만나면 루프 종료
  5. 끊고 다음 위치 저장

    • *s != '\0'(=구분자를 만남)이면 그 자리를 '\0'끊고, *save_ptr = s + 1로 다음 후보 시작점을 저장

    • *s == '\0'(=문자열 끝에 도달)이면 *save_ptr = s(끝을 가리키게) 저장

  6. 토큰 주소 반환

    • return token; — 최소 1글자 이상의 토큰만 반환(선행 구분자는 이미 건너뜀)