본문 바로가기
개발/C, C++

C++ split 함수 구현

by 피로물든딸기 2021. 5. 8.
반응형

C, C++ 전체 링크

 

아래의 string을 ","로 구분하여 a / b / c / d / ef / ghi / jkl / mn / opqr 이 되도록 해보자.

a,b,c,d,ef,ghi,jkl,mn,opqr

즉, str을 ","로 split하여 vector<string>의 결과를 얻어보자.

 

C언어에서 문자열의 끝은 0으로 구분한다.

따라서 split의 종료는 0이 될 때 종료할 수 있다.

 

그러나 linux로 file 작업을 하다보면 문자열의 끝이 0이 아닌 경우가 종종 있다.

뭔가 작업이 잘 안된다면 char type%d로 출력하면 정체를 확인할 수 있다.

여러 상황이 있겠지만, 경험상 ASCII 코드의 10번인 개행문자 '\n'와 13번인 Line Feed가 있다.

 

이러한 값들이 대부분 실제 vi로 보이지 않고,

Linux나 Window에서 파일 작업을 번갈아 하다 보면 생겨서, file을 작업할 때 애먹을 수 있다.


이제 split을 구현해보자.

구현할 함수의 return 값은 vector<string>이고 split할 string과 구분자 delimiter가 필요하다.

vector<string> split(string str, char delimiter)

 

for문을 이용해 string을 순회하면서 임시 string temp에 문자 하나하나를 push한다.

그러다가 delimiter가 되면, vector<string>push하고, temp는 초기화한다.

 

위에서 설명한 것처럼 문자열의 마지막이 0, 10, 13이 될 때 종료한다.

마지막 split된 문자는 for문이 종료되기 전에 push하지 않으므로, 한번 더 push하고 vector<string>을 return한다.

 

코드로 구현하면 아래와 같다.

vector<string> split(string str, char delimiter)
{
	vector<string> vs;
	string temp;

	for (int i = 0; !(str[i] == 13 /* Line Feed */ || str[i] == '\n' || str[i] == 0); i++)
	{
		if (str[i] == delimiter) /* 구분자를 만나는 경우 push 후 clear */
		{
			vs.push_back(temp);
			temp.clear();

			continue;
		}

		/* temp에 문자를 하나씩 담는다. */
		temp.push_back(str[i]);
	}

	/* 마지막 string은 push되지 않았으므로 for문 밖에서 push */
	vs.push_back(temp); 

	return vs;
}

 

string의 초기화는 clear 메서드를 사용하면 된다.

 

전체 코드 및 test 결과는 아래와 같다.

#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<string> split(string str, char delimiter)
{
	vector<string> vs;
	string temp;

	for (int i = 0; !(str[i] == 13 /* Line Feed */ || str[i] == '\n' || str[i] == 0); i++)
	{
		if (str[i] == delimiter)
		{
			vs.push_back(temp);
			temp.clear();

			continue;
		}

		temp.push_back(str[i]);
	}

	vs.push_back(temp);

	return vs;
}

int main(void)
{
	string str = "a,b,c,d,ef,ghi,jkl,mn,opqr";
	vector<string> spt = split(str, ',');

	for (int i = 0; i < spt.size(); i++) 
		printf("%s ", spt[i].c_str());
	putchar('\n');

	/* vector<string>을 iterator로 순회 */
	for (vector<string>::iterator iter = spt.begin(); iter != spt.end(); iter++) 
		cout << *iter << " ";
	putchar('\n');

	return 0;
}

원래 stringvector<string>에 잘 split 된 것을 알 수 있다. 

반응형

댓글