C++ 프로그래밍을 하다 보면 쉼표(,)로 구분된 하나의 긴 문자열을 개별 항목으로 나누어야 하는 경우가 자주 발생합니다. 예를 들어 CSV 형식의 데이터나 사용자 입력을 처리할 때가 대표적입니다. 이번 글에서는 getline() 함수와 stringstream을 활용해 쉼표로 구분된 문자열을 파싱하고, 그 결과를 vector 객체에 저장하는 방법을 단계별로 살펴보겠습니다.
getline() 함수란?
문자열을 분리할 때는 getline() 함수를 사용합니다. 이 함수의 기본 문법은 다음과 같습니다.
getline(input_stream, string, delim)
getline()은 입력 스트림으로부터 문자열이나 한 줄을 읽어오는 함수입니다. 세 번째 인자인 구분자(delim)를 지정하면 해당 문자를 기준으로 문자열을 잘라낼 수 있으며, 기본값은 줄바꿈 문자('\n')입니다.
입력 및 출력 예시
입력: "ABC,XYZ,Hello,World,25,C++" 출력: ABC XYZ Hello World 25 C++
알고리즘
전체 동작 흐름은 다음과 같습니다.
1단계: 주어진 문자열로부터 스트림을 생성한다. 2단계: 스트림이 끝날 때까지 반복한다. 2-1단계: 쉼표 앞에 있는 항목을 추출한다. 2-2단계: 추출한 항목을 vector에 추가한다. 3단계: 결과 vector를 반환한다.
예제 코드
#include<iostream>
#include<vector>
#include<sstream>
using namespace std;
int main() {
string my_str = "ABC,XYZ,Hello,World,25,C++";
vector<string> result;
// 문자열로부터 stringstream 생성
stringstream s_stream(my_str);
while(s_stream.good()) {
string substr;
getline(s_stream, substr, ','); // 쉼표로 구분된 첫 번째 문자열 가져오기
result.push_back(substr);
}
// 분리된 모든 문자열 출력
for(int i = 0; i<result.size(); i++) {
cout << result.at(i) << endl;
}
return 0;
}
실행 결과
ABC XYZ Hello World 25 C++
코드 설명
동작 과정을 간단히 정리하면 다음과 같습니다.
- stringstream 생성:
my_str문자열을stringstream으로 감싸 일반 입력 스트림처럼 다룰 수 있게 합니다. - 반복 추출:
getline(s_stream, substr, ',')을 호출할 때마다 쉼표 직전까지의 내용이substr에 저장되고, 스트림 위치는 쉼표 다음으로 이동합니다. - 결과 저장: 추출된 각 항목은
push_back()을 통해vector에 순서대로 저장됩니다. - 출력: 마지막으로 반복문을 통해 분리된 문자열들을 한 줄씩 출력합니다.
더 깔끔하게 작성하는 팁
s_stream.good()으로 조건을 검사하는 대신, getline()의 반환값을 직접 활용하면 코드를 더 간결하고 안전하게 만들 수 있습니다. getline()은 스트림 객체를 반환하므로 조건문에서 참/거짓 판별이 가능합니다.
vector<string> split(const string& str, char delim = ',') {
vector<string> tokens;
stringstream s_stream(str);
string item;
while(getline(s_stream, item, delim)) {
if(!item.empty()) {
tokens.push_back(item);
}
}
return tokens;
}
이렇게 함수로 감싸 두면 어떤 문자열이든 손쉽게 재사용할 수 있고, 빈 항목을 걸러내는 처리도 함께 적용할 수 있습니다. 또한 C++20 이상을 사용한다면 std::ranges::views::split을 활용하는 방법도 있으니 참고해 보시기 바랍니다.