예전에 strchr 함수를 알려준 적이 있었습니다. 이 글에서요. 이 함수가 strchr과 다른 점은
- strchr은 한 문자에 대해서만 동작하지만
- c언어 strpbrk 함수의 경우, 여러 문자에 대해서 동작한다는 것입니다.
어떻게 쓰는지 간략하게 알아봅시다.
c언어 strpbrk 함수
string.h에 있는 문제 함수의 사용법은 아래와 같습니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb1.png)
어려워 보이는데요. 하나씩 보겠습니다.
- dest
- 타겟 문자열을 의미합니다.
- breakset
- delimeter의 목록을 의미합니다.
- !과 #을 구분자로 삼는 경우
- “!#”가 되겠습니다.
- delimeter의 목록을 의미합니다.
- 리턴값
- dest로부터 구분자를 찾은 최초의 위치입니다.
- 없다면 NULL 포인터를 돌려줍니다.
즉, 어떤 문자열에서 특정한 문자들이 최초로 나타나는 위치를 찾을 때 쓰입니다. 예제 2개를 보겠습니다.
1번째 예제
먼저, 1번을 보겠습니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb2.png)
먼저, 1번째 strpbrk를 봅시다.
- 타겟 문자열은 str입니다.
- stop word는 . (온점)과 공백입니다.
즉, 1번째의 경우, str에서 “.”이나 ” “가 나오는 최초의 위치를 찾는 것입니다. 2번째의 경우는 어떨까요?
- 타겟 문자열은 str2입니다.
- stop word는 . (온점)과 공백입니다.
2번째의 경우에도, stop word는 동일합니다. 단지, 타겟 문자열이 “bb cc.dd”라는 점이 다릅니다. 이 때, 1번 예제는 어떻게 동작할까요?
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb6.png)
.이나 공백이 str에서 나타난 최초의 위치는 노란색 부분입니다. 따라서, 노란색 위치가 리턴되는 값입니다. 그림에서 회색 부분은 널 문자입니다. 따라서, 노란색 부분과 군청색 부분이 출력됩니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb7.png)
str2는 어떨까요? 마찬가지입니다. .이나 공백이 나타난 최초의 위치가 노란색 부분이고, 회색 부분이 널 문자입니다. 따라서 노란색 부분과 군청색 부분이 출력되게 됩니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb3.png)
1번 프로그램의 출력 결과는 위와 같습니다. 먼저 “.cc dd”가 출력되었고, 그 다음에 ” cc.dd”가 출력되었음을 알 수 있습니다.
2번째 예제
이제 2번째 예제를 보겠습니다. 사실 2번째의 경우, strtok를 쓰면 깔끔하게 처리할 수 있습니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb4.png)
“bb.cc dd “에서, . (온점)과 공백 문자를 구분자로 해서 토큰을 분리하려고 합니다. 어떻게 하면 될까요? strpbrk의 리턴값이 null이 아닐 때 까지 돌리면 됩니다. 그런데, 포인터가 2개 있어요. 2개의 변수 prev와 pos는 아래의 역할을 합니다.
- prev
- loop가 돌 때 마다, pos의 위치를 저장합니다.
- pos
- loop가 돌 때, 구분자를 찾은 최초의 위치를 가리킵니다.
이제 예제를 분석해 봅시다. 1번째 loop를 돌려 봅시다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb8.png)
1번째 loop를 돌 때, prev와 pos는 맨 앞의 b를 가리키고 있었어요. 그리고, strpbrk를 호출했는데요. 이 때, .이나 공백 문자가 나온 최초의 위치가 3번째 위치였습니다. 따라서, pos는 3번째 위치에 있는 .을 가리킵니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb9.png)
이 위치는 NULL 포인터가 아닙니다. 따라서, 해당 위치에 null 문자를 추가합니다. 이제, prev부터 문자열을 출력하라고 하면, 노란색 부분만 출력될 겁니다. 다음에 pos가 하나 증가하는데, 이는 맨 처음 찾은 구분자의 위치이기 때문입니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb10.png)
이제, prev는 4번째 위치로 이동합니다. 옅은 회색으로 칠한 영역 중, 공백이나, .이 나타나는 제일 빠른 위치는 6번째 위치입니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb11.png)
따라서, 6번째 위치에 NULL 문자를 넣고, prev부터 시작하는 문자열을 출력합니다. 그러면 노란색 부분만 출력되겠지요. 다음에, pos는 하나 증가시킵니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb12.png)
이제, prev는 7번째로 이동합니다. 만약에, 공백이나 .을 회색 영역에서 찾지 못했다면, pos는 NULL이 될 겁니다. 그러면 회색 부분 그대로 출력하면 됩니다. while loop에는
- pos가 NULL 포인터가 아니고
- *pos가 0이 아니다.
라는 조건이 걸려 있음을 알 수 있는데요. 널 문자를 만나면 문자열의 끝이기 때문입니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/strb5.png)
2번 프로그램의 결과는 위와 같습니다. bb, cc, dd 순서대로 출력되었습니다.