Home » 레퍼런스 » C » c언어 strpbrk 함수로 여러 delimeter 의 최초 시작 위치를 알아봅시다.

c언어 strpbrk 함수로 여러 delimeter 의 최초 시작 위치를 알아봅시다.

예전에 strchr 함수를 알려준 적이 있었습니다. 이 에서요. 이 함수가 strchr과 다른 점은

  • strchr은 한 문자에 대해서만 동작하지만
  • c언어 strpbrk 함수의 경우, 여러 문자에 대해서 동작한다는 것입니다.

어떻게 쓰는지 간략하게 알아봅시다.


c언어 strpbrk 함수

string.h에 있는 문제 함수의 사용법은 아래와 같습니다.

[그림 1] 함수의 원형

어려워 보이는데요. 하나씩 보겠습니다.

  • dest
    • 타겟 문자열을 의미합니다.
  • breakset
    • delimeter의 목록을 의미합니다.
      • !과 #을 구분자로 삼는 경우
      • “!#”가 되겠습니다.
  • 리턴값
    • dest로부터 구분자를 찾은 최초의 위치입니다.
    • 없다면 NULL 포인터를 돌려줍니다.

즉, 어떤 문자열에서 특정한 문자들이 최초로 나타나는 위치를 찾을 때 쓰입니다. 예제 2개를 보겠습니다.


1번째 예제

먼저, 1번을 보겠습니다.

[그림 2] 1번 예제 프로그램

먼저, 1번째 strpbrk를 봅시다.

  • 타겟 문자열은 str입니다.
  • stop word는 . (온점)과 공백입니다.

즉, 1번째의 경우, str에서 “.”이나 ” “가 나오는 최초의 위치를 찾는 것입니다. 2번째의 경우는 어떨까요?

  • 타겟 문자열은 str2입니다.
  • stop word는 . (온점)과 공백입니다.

2번째의 경우에도, stop word는 동일합니다. 단지, 타겟 문자열이 “bb cc.dd”라는 점이 다릅니다. 이 때, 1번 예제는 어떻게 동작할까요?

.이나 공백이 str에서 나타난 최초의 위치는 노란색 부분입니다. 따라서, 노란색 위치가 리턴되는 값입니다. 그림에서 회색 부분은 널 문자입니다. 따라서, 노란색 부분과 군청색 부분이 출력됩니다.

str2는 어떨까요? 마찬가지입니다. .이나 공백이 나타난 최초의 위치가 노란색 부분이고, 회색 부분이 널 문자입니다. 따라서 노란색 부분과 군청색 부분이 출력되게 됩니다.

[그림 3] 예제 1번의 출력 결과

1번 프로그램의 출력 결과는 위와 같습니다. 먼저 “.cc dd”가 출력되었고, 그 다음에 ” cc.dd”가 출력되었음을 알 수 있습니다.


2번째 예제

이제 2번째 예제를 보겠습니다. 사실 2번째의 경우, strtok를 쓰면 깔끔하게 처리할 수 있습니다.

[그림 4] 예제 2번 프로그램

“bb.cc dd “에서, . (온점)과 공백 문자를 구분자로 해서 토큰을 분리하려고 합니다. 어떻게 하면 될까요? strpbrk의 리턴값이 null이 아닐 때 까지 돌리면 됩니다. 그런데, 포인터가 2개 있어요. 2개의 변수 prev와 pos는 아래의 역할을 합니다.

  • prev
    • loop가 돌 때 마다, pos의 위치를 저장합니다.
  • pos
    • loop가 돌 때, 구분자를 찾은 최초의 위치를 가리킵니다.

이제 예제를 분석해 봅시다. 1번째 loop를 돌려 봅시다.

1번째 loop를 돌 때, prev와 pos는 맨 앞의 b를 가리키고 있었어요. 그리고, strpbrk를 호출했는데요. 이 때, .이나 공백 문자가 나온 최초의 위치가 3번째 위치였습니다. 따라서, pos는 3번째 위치에 있는 .을 가리킵니다.

이 위치는 NULL 포인터가 아닙니다. 따라서, 해당 위치에 null 문자를 추가합니다. 이제, prev부터 문자열을 출력하라고 하면, 노란색 부분만 출력될 겁니다. 다음에 pos가 하나 증가하는데, 이는 맨 처음 찾은 구분자의 위치이기 때문입니다.

이제, prev는 4번째 위치로 이동합니다. 옅은 회색으로 칠한 영역 중, 공백이나, .이 나타나는 제일 빠른 위치는 6번째 위치입니다.

따라서, 6번째 위치에 NULL 문자를 넣고, prev부터 시작하는 문자열을 출력합니다. 그러면 노란색 부분만 출력되겠지요. 다음에, pos는 하나 증가시킵니다.

이제, prev는 7번째로 이동합니다. 만약에, 공백이나 .을 회색 영역에서 찾지 못했다면, pos는 NULL이 될 겁니다. 그러면 회색 부분 그대로 출력하면 됩니다. while loop에는

  • pos가 NULL 포인터가 아니고
  • *pos가 0이 아니다.

라는 조건이 걸려 있음을 알 수 있는데요. 널 문자를 만나면 문자열의 끝이기 때문입니다.

[그림 5] 예제 2번 프로그램의 결과

2번 프로그램의 결과는 위와 같습니다. bb, cc, dd 순서대로 출력되었습니다.

Leave a Comment

1 × 3 =