본문 바로가기

프로그래밍 언어 (プログラミング言語)/C && C++

C++에서 문자열을 Parsing하는 다양한 방법

1. substr()으로 문자열 자르기

substr()은 문자열의 Index에서 원하는 길이의 문자열을 잘라서 string으로 리턴합니다.

substr의 Syntax는 아래와 같습니다. 인자로 index와 길이를 받고 string을 리턴합니다.

string substr (size_t pos = 0, size_t len = npos) const;

아래 예제는 문자열의 특정 부분을 자르는 코드입니다. substr(0, 5)는 Index 0에서 시작하는 5개의 문자를 잘라서 string으로 리턴합니다. substr(6, 5)는 Index 6에서 길이 5의 문자열을 잘라서 리턴합니다.

#include <iostream>
#include <string>

int main () {

    std::string str = "Hello World, C++";

    std::string newstr1 = str.substr(0, 5);
    std::string newstr2 = str.substr(6, 5);
    std::string newstr3 = str.substr(13, 3);

    std::cout << newstr1 << std::endl;
    std::cout << newstr2 << std::endl;
    std::cout << newstr3 << std::endl;

    return 0;
}

Output:

Hello
World
C++

substring(6)처럼 Index만 인자로 전달하고 길이는 전달하지 않으면 문자열의 마지막까지 자릅니다. 아래와 같이 substr(6)은 Index 6에서 문자열의 마지막까지 잘라서 string으로 리턴합니다. substr(13)은 Index 13에서 문자열 마지막까지 잘라서 리턴합니다.

#include <iostream>
#include <string>

int main () {

    std::string str="Hello World, C++";

    std::string newstr1 = str.substr(6);
    std::string newstr2 = str.substr(13);

    std::cout << newstr1 << std::endl;
    std::cout << newstr2 << std::endl;

    return 0;
}

Output:

World, C++
C++

2. substr()과 find()로 문자열 분리하기

find(separator, index)는 인자로 전달된 Index에서 separator를 찾고 그 Index를 리턴합니다. separator가 없으면 npos를 리턴합니다.

아래 예제는 find()와 substr()을 이용하여 ,를 기준으로 문자열을 분리하는 예제입니다. 문자열 "Hello,World,C++"는 아래 코드에서 Hello, World, C++으로 분리됩니다. 동작 원리는 while 안에서 문자열의 :를 찾고 substr()으로 : 직전까지 문자열을 자르는 것입니다.

#include<iostream>
#include<string>

int main() {

    std::string str = "Hello,World,C++";
    std::string separator = ",";
    int cur_position = 0;
    int position;

    while ((position = str.find(separator, cur_position)) != std::string::npos) {
        int len = position - cur_position;
        std::string result = str.substr(cur_position, len);
        std::cout << result << std::endl;
        cur_position = position + 1;
    }

    std::string result = str.substr(cur_position);
    std::cout << result << std::endl;
}

Output:

Hello
World
C++

3. getline()과 istringstream으로 문자열 분리하기

getline()과 istringstream을 이용하여 위와 같이 구분자로 문자열을 분리할 수 있습니다. 문자열을 istringstream으로 변환하고, getline()을 통해 구분자를 기준으로 문자열을 읽어올 수 있습니다.

#include<iostream>
#include<string>
#include<sstream>

int main() {

    std::string str = "Hello,World,C++";
    char separator = ',';
    std::istringstream iss(str);
    std::string str_buf;
    while (getline(iss, str_buf, separator)) {
    	  std::cout << str_buf << std::endl;
    }

    return 0;
}

Output:

Hello
World
C++

 

 

C언어 혹은 C++에서 자신이 원하는 문자열을 잘라낼 때 사용하는 함수로 strtok라는 함수가 있습니다. 이 함수는 string token의 약자로 인자 값으로 전달받은 매개변수를 구분자로 하여 문자열을 잘라내어 return 합니다. 만약 더 이상 자를 문자열이 없다면 NULL을 반환합니다.

 

문자열을 자르는 방식

M Y   N A M E   I S   T O M \0
M Y \0 N A M E   I S   T O M \0
M Y \0 N A M E \0 I S   T O M \0
M Y \0 N A M E \0 I S \0 T O M \0

C언어 또는 C++에서 문자열은 \0으로 종료가 되게 되어있습니다. 그렇기에 인자로 받은 문자열에서 구분자가 있는 위치를 널 포인트로 치환해줌으로써, 문자열을 끊기게 만듭니다. 예를 들어 공백을 구분자로 뒀을 경우 위와 같은 방식으로 문자열이 잘리게 됩니다.

 

strtok 함수 형식

char *strtok(char *_String, const char *_Delimit);
char *strtok_s(char *_String, const char *_Delimit, char **_Context);

String : 자르고자 하는 문자열

Delimit : 자를 기준을 정하는 구분자

Context : 분할 한 문자열

 

strtok 함수 사용 예제

#include <stdio.h>
#include <string.h> //strtok 함수가 선언된 헤더 파일
//#include <cstring> //C++일 경우

int main() {
    char str[] = "MY NAME IS TOM"; //대상 문자열 
    char *temp = strtok(str," "); //공백을 기준으로 문자열 자르기
    
    while (temp != NULL) { //널이 아닐때까지 반복
        printf("%s\n",temp); // 출력
        temp = strtok(NULL, " ");	//널문자를 기준으로 다시 자르기
    }
	
    return 0;
}

strtok 함수는 잘린 문자열을 한 번에 얻을 수 없어서 while 반복문으로 문자열을 계속 자르다가 문자열이 나오지 않으면 반복문을 끝내는 방식으로 사용합니다. strtok 함수는 더 이상 자를 수가 없으면 NULL값을 리턴하므로 NULL값이 리턴될 때까지 반복하여 문자열을 자르는 방식입니다.

 

strtok_s 함수 사용 예제

#include <stdio.h>
#include <string.h> //strtok 함수가 선언된 헤더 파일
//#include <cstring> //C++일 경우

int main() {
    char str[] = "MY NAME IS TOM"; //대상 문자열 
    char* str2 = NULL;
    char* temp = strtok_s(str, " ", &str2); //공백을 기준으로 문자열 자르기

    while (temp != NULL) { //널이 아닐때까지 반복
        printf("잘린 문자열 : %s\n", temp); // 출력
        printf("자르고 남은 문자열 : %s\n", str2);
        temp = strtok_s(NULL, " ", &str2);	//널문자를 기준으로 다시 자르기
    }

    return 0;
}

strtok_s 함수는 strtok 함수를 개선한 함수입니다. 인자값으로 자르고 남은 문자열을 저장하는 위치 context의 주소를 받는다는것을 제외하면 strtok함수와 같습니다. strtok함수를 더욱 안전하게 사용하려면 strtok_s 함수를 사용해보세요.

 

strtok 함수 구현

#include <stdio.h>

char* my_strtok(char* str, const char* delimiters ){
   static char* pCurrent;
   char* pDelimit;

   if ( str != NULL )pCurrent = str;
   else str = pCurrent;

   if(*pCurrent == NULL) return NULL;

   //문자열 점검
   while (*pCurrent)
   {
       pDelimit = (char*)delimiters ;
       
       while (*pDelimit){
         if(*pCurrent == *pDelimit){
               *pCurrent = NULL;
               ++pCurrent;
               return str;
            }
            ++pDelimit;
       }
       ++pCurrent;
   }
    // 더이상 자를 수 없다면 NULL반환
    return str;
}

int main(){
  char str[] = "MY NAME IS TOM"; //대상 문자열 
  char *temp = my_strtok(str," "); //공백을 기준으로 문자열 자르기
  
  while (temp != NULL) { //널이 아닐때까지 반복
      printf("%s\n",temp); // 출력
      temp = my_strtok(NULL, " ");	//널문자를 기준으로 다시 자르기
  }
}

 

'프로그래밍 언어 (プログラミング言語) > C && C++' 카테고리의 다른 글

C++ - Stack(STL)  (0) 2023.01.11
STL lower_bound() upper_bound()  (0) 2022.12.18
STL Binary Search function  (0) 2022.12.18
(ordered) Map vs Unordered Map  (0) 2022.12.18
Map vs Multimap  (0) 2022.12.18