개발자공부일기
C++ stringstream 사용법 본문
stringstream으로 C++에서 문자열 다루기
개발하다 보면 문자열을 숫자로 바꾸거나, 공백 또는 구분자를 기준으로 잘라야 할 일이 있습니다.
전화번호 "010-1234-5678"를 쪼개거나 "5000"이라는 문자열을 숫자 5000으로 바꾸는 작업이 그 예입니다.
이때마다 복잡한 루프나 substr()을 쓰기보다는, C++의 stringstream라는 친구가 있습니다.
stringstream이란?
C++ 표준 라이브러리 <sstream>에 포함된 stringstream은 문자열을 cin처럼 다룰 수 있게 해주는 클래스입니다.
즉, 문자열을 스트림에 싣고, 그 안에서 >>, <<, getline() 등을 사용해 데이터를 쉽게 꺼내거나 추가할 수 있습니다.
- cin: 키보드 입력을 받는 스트림
- stringstream: 문자열을 입력처럼 다루는 스트림
기본 사용법
1. >> 연산자 – 공백 기준으로 문자열 자르기
string str = "10 20 30";
stringstream ss(str);
int a, b, c;
ss >> a >> b >> c; // 공백 기준으로 분리
출력:
10, 20, 30
2. getline(스트림, 변수, 구분자) – 구분자 기준 파싱
string phone = "010-1234-5678";
stringstream ss(phone);
string token;
while (getline(ss, token, '-')) {
cout << token << "\n";
}
출력:
010
1234
5678
이 방법은 전화번호, 날짜, CSV 등 특정 구분자를 기준으로 문자열을 잘라야 할 때 매우 유용합니다.
3. str() – 문자열 가져오기와 설정
stringstream ss;
ss << "Hello " << "World";
cout << ss.str(); // Hello World
ss.str("123 456"); // 새로운 문자열로 초기화
int a, b;
ss >> a >> b; // a = 123, b = 456
- ss.str()은 현재 버퍼 내용을 문자열로 반환
- ss.str("문자열")은 새 문자열로 스트림을 교체
4. clear() – 스트림 재사용 시 필수
stringstream ss("100 200");
int x, y;
ss >> x >> y;
ss.clear(); // 상태 초기화
ss.str("300 400"); // 새 문자열 입력
ss >> x >> y;
stringstream은 한 번 끝까지 읽으면 EOF 상태가 되어 재사용이 안 됩니다.
그래서 재사용 전에는 반드시 clear()로 상태를 초기화해야 하며, str()로 새로운 문자열을 설정해야 합니다.
문자열 → 숫자 변환도 간단하게
string str = "5000";
stringstream ss(str);
int num;
ss >> num;
cout << num + 1000; // 6000
stoi()를 써도 되지만, stringstream은 여러 개의 값을 동시에 처리할 수 있어 더 유연합니다.
구분자 기반 데이터 파싱 – CSV 예제
string line = "홍길동,25,서울";
stringstream ss(line);
string token;
while (getline(ss, token, ',')) {
cout << token << "\n";
}
결과:
홍길동
25
서울
CSV 파일이나 사용자 입력 데이터를 파싱할 때 특히 유용합니다.
날짜 분리 예제 – getline() 반복 호출
string date = "2025-08-22";
stringstream ss(date);
string year, month, day;
getline(ss, year, '-');
getline(ss, month, '-');
getline(ss, day, '-');
날짜를 연도, 월, 일로 나눠야 할 때도 한 줄 코드로 분리 가능합니다.
출력 메시지 조합 – ostringstream 활용
ostringstream oss;
oss << "이름: " << "홍길동" << ", 나이: " << 25;
cout << oss.str(); // 이름: 홍길동, 나이: 25
ostringstream은 문자열을 계속 덧붙이는 데 유용하며, + 연산보다 훨씬 효율적이고 직관적입니다.
템플릿 기반 출력에서도 널리 사용됩니다.
istringstream / ostringstream 차이점은?
- stringstream: 입력과 출력 모두 가능
- istringstream: 입력 전용 (읽기)
- ostringstream: 출력 전용 (쓰기)
대부분의 경우 stringstream 하나로 충분하지만, 용도에 따라 구분해서 쓰면 코드의 의도가 더 명확해집니다.
성능은 괜찮을까?
- 일반적인 문자열 파싱/조립에는 성능 부담이 거의 없습니다.
- 고성능이 필요한 반복 루프에서는 stringstream보다는 std::string::append()나 substr() 등을 직접 사용하는 게 나을 수 있습니다.
요약
- 여러 타입을 한 번에 연결/추출할 수 있어 형 변환 스트레스 없음
- 복잡한 문자열 처리, 입력 파싱, 테스트 메시지 출력 등에 매우 유용
- 재사용 시 clear() + str() 조합은 필수 기억
- 스트림 기반 로직은 깔끔한 코드 작성에 큰 도움이 됨