Home » 레퍼런스 » C++ » c++ string find_first_of 함수를 알아봅시다.

c++ string find_first_of 함수를 알아봅시다.

c++ string find_first_of 함수는 string에서 처음으로 나타나는 구분자들의 위치를 찾습니다. 이것이 find와 다른 점입니다.

  • find
  • find_first_of [현재글]

예를 들어, 해당 함수의 1번째 인자에 “.!”을 넘기는 경우, string에서 문자 ‘.’나, ‘!’가 나타나는 최초의 위치를 찾게 됩니다.


함수에 대한 설명

find_first_of 함수는 아래와 같이 씁니다.

  • 1번째 인자로 delimeter를 받습니다.
    • 예를 들어, 문자열 안에서 !나, $가 나타나는 최초의 위치를 찾고 싶은 경우
    • delimeter로 “!$” 를 넘겨주면 됩니다.
  • 2번째 인자는
    • target 문자열의 몇 번째 위치부터 탐색을 시작할 것인지를 나타냅니다.
    • 설정하지 않은 경우 default로 0입니다.
  • 리턴값
    • delimeter 안에 있는 문자들을 찾은 경우 최초로 찾은 위치를
    • 못 찾으면 -1을 돌려줍니다.

몇 가지 도식화 된 그림을 보겠습니다.

타겟 문자열이 위와 같다고 해 보겠습니다. “t#g!a”입니다. 여기서 delimeter를 “#!”로 설정해 보겠습니다. 2번째 인자 pos를 따로 넣지 않은 경우, pos는 0입니다. 따라서, 회색 부분에 대해서 탐색하게 될 겁니다.

delimeter가 “#!”라는 의미는

  • 문자가 ! 이거나
  • 혹은 문자가 # 인

최초의 위치를 찾으라는 의미입니다.

노란색 위치에서 최초로 나타납니다. 따라서, 이 때 string의 find_first_of는 1을 돌려줍니다.

pos를 2로 둔 경우에는 어떨까요? 이 경우, 회색 부분, 즉 ‘g’부터 탐색하게 됩니다.

#은 회색 부분에 속하지 않았기 때문에 제외됩니다. 회색 부분 중에서 최초로 !이나 #가 나타나는 위치는 3번째 위치입니다. 따라서, delimeter를 “!#”로 설정하고, pos를 2로 둔 경우 1이 아닌 3이 리턴됩니다.

pos를 4로 둔 경우에는 어떨까요? delimeter는 “!#”로 두었습니다. 그러면 회색 부분을 탐색할 겁니다. 회색 부분에서 문자 !이나, #는 없으므로, -1이 리턴됩니다.

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

이제, 예제 1번 프로그램을 보겠습니다. target이 “this#is# … “이고, 구분자가 “#. “입니다. 공백이거나, #이거나, 문자 .입니다. 먼저, 8번째 줄에서

  • target 문자열의 0번째 위치부터
  • 공백이나, #이나, 문자 .가 최초로 출현하는 위치를 찾습니다.

어딘가요?

4번째 위치입니다. 따라서, 첫 번째로 출력되는 값은 4가 됩니다. 다음에, pos 값이 index + 1이 되는데요. index 값이 4였으므로, 위치 5부터 탐색을 하게 됩니다.

회색 부분에서 다음 #이나, 문자 .나 공백이 나타나는 최초의 위치는 어디인가요? 7번째 위치입니다. 따라서, 예제 1번 프로그램은 4와 7을 한 줄에 하나씩 출력하게 됩니다.

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

예제 1번 프로그램의 출력 결과는 위와 같습니다.


실전 예제

이 글에서 배운 c++ string find_first_of 함수를 이용해서, 실전 예제 하나를 풀어봅시다. 여러 구분자를 가지고 문자열을 token화 시키는 프로그램을 만들어 봅시다.

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

예제 2번 프로그램을 봅시다. 먼저 변수부터 봅시다.

  • prev
    • 새로운 토큰의 시작 위치를 의미합니다.
  • cur
    • prev 로부터 delimeter들을 찾은 최초의 위치를 의미합니다.

이 두 변수를 볼 거에요. 이제, while loop를 볼까요?

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

길어 보이는데 별 거 없습니다. 일단, 처음 prev 값이 0입니다. 만약에 찾았다면 어떻게 해야 할까요? 찾은 위치가 cur라면, cur – prev의 길이의 부분 문자열이 나오게 됩니다. 따라서, prev가 cur보다 작다면 부분 문자열을 만들어서 출력하면 됩니다.

그리고, prev에 cur+1을 했습니다. 이는, 최초로 찾은 위치 다음부터 또 탐색하기 위해서입니다.

그러면 설령 토큰이 탐색 범위에 없어서 -1이 리턴된다고 하여도, 토큰의 시작 위치는 prev에 저장되어 있겠지요. 따라서, while loop 바깥에서, prev 위치부터 시작하는 substring을 출력하면 됩니다.

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

2번 예제 프로그램의 결과는 위와 같습니다.

Leave a Comment

3 × 2 =