플랫폼/C++

Stringstream 사용법 정리

방랑여행 2013. 7. 17. 11:20

헤더 : <sstream>

 

stringstream은, 주어진 문자열에서 필요한 정보를 빼낼 때 유용하게 사용된다.

간단한 사용 예를 보자.

float num;
stringstream stream1;

string string1 = "25 1 3 .235\n1111111\n222222";	  
stream1.str(string1);
while( stream1 >> num )
	cout << "num: " << num << endl;  // displays numbers, one per line

 

이 코드는, 저 문자열에서 실수 형태의 정보를 num에 저장하고 출력하는 것이다.

실제로 float 형태의 변수에 25, 1, 3, ... 등의 값들이 각각 저장되는 것으로, 매우 유용하다.

 

출력 결과는, 6개 줄에 걸쳐 "num : " 옆에 25, 1, 3 0.235, 1111111, 222222 가 출력된다.

공백과 \n을 무시하고, 숫자 정보만 빼낸 것이다.

while(stream1 >> num)이란, 더 이상 num의 자료형에 맞는 정보가 없을 때까지

계속 스트림에서 num으로 자료를 추출/복사하는 것이다. 끝에 도달하면 끝난다.

(즉, 만일 주어진 string이 "23 259 .326 22 a 15" 인 경우,

num이 int이면 259까지만, num이 float이면 22까지만 추출하고 멈춘다.)

 

여기서 특이한 것은, float 자료형에 맞게 .235를 0.235로 저장한다는 것이다.

만일 위와 똑같은 코드에서 맨 윗줄만 바꿔서, float num 대신 string num으로 선언하였을 경우,

이번엔 float 형태가 아니라 string 형태이기 때문에,

문자열 내에 존재하는 .235는 앞서와 달리 0.235로 바뀌지 않고 그냥 ".235" 가 된다.

 

여기서 주의할 점은, 값을 추출한다고 해서, stringstream에 있는 값들이 변하는 것은 아니라는 것이다.

마지막 값까지 모두 추출했다고 하더라도,  stringstream에 저장된 값은 처음과 변함없이

"25 1 .235\n1111111\n222222" 가 되어 있다.

____________________________________________________________

 

str() 함수에 관하여 - str() 함수가 사용되는 방법은 2가지이다.

 

1. str(string s)

  - 현재 stringstream의 값을 s 로 바꾼다.

2. str()

  - 현재 stringstream이 저장하고 있는 문자열의 복사본을 반환한다.

 

clear 함수에 관하여

1. 정확히 뭘 clear하는지 모르겠다. 확실한 것은 stringstream에 저장된 문자열을 clear하지는 않는다는 것 !!

    - stringstream에 저장된 문자열을 삭제하고 싶으면, stringstream ss; ss.str("")를 사용하면 된다.

2. clear를 실시한 경우에만, str(string s)로 새로운 문자열을 받았을 때 첫 위치부터 추츨이 가능하다.

 

 

둘을 모두 이용하면 stringstream 변수를 새로운 문자열을 받는 데에 재사용 할 수 있다.

string str1 = "23 259 .326 22 a 15";
string str2 = "1 263avj 3135df 3235 baij af9i39a fklk30";

stringstream ss(str1);	
string k;
while(ss >> k)	cout << k << endl;

ss.clear();
ss.str(str2);
while(ss >> k)	cout << k << endl;

 

이 코드에서 clear()이 없는 경우, str2를 저장해도 여기서 값을 추출할 수 없다.

이전의 string에서 이미 끝까지 도달했다는 flag가 올라가서, 더 이상 값이 추출되지 않기 때문이다.

그러한 flag bit들을 초기화시키는 것이 clear()으로 보인다.

____________________________________________________________

 

<활용 팁>

 

다음과 같은 input이 들어온다고 해 보자. (vector<string>이라고 하자)

[0] - "1 Kim 89"

[1] - "2 Park 52"

[2] - "3 Moon 100"

[3] - "4 Jun 95"

...

 

이러한 input에서, 각 번호/이름/점수를 각각 나누어 저장해야 할 때, 어떻게 하면 좋을 것인가?

vector input(3, "");	// given input
input[0] = "1 Kim 89";
input[1] = "2 Moon 100";
input[2] = "3 Chan 78";

for(int i = 0; i < input.size(); i++)
{
	int num, score;
	string name;

	stringstream ss;	ss.str(input[i]);

	ss >> num;
	ss >> name;
	ss >> score;

	cout << num << " " << name << " " << score << endl;
	// 이후 필요한 자료 구조에 저장하여 활용한다.
}

 

'플랫폼 > C++' 카테고리의 다른 글

공백을 포함해 한 줄 입력받기  (0) 2013.07.09
Reverse_iterator 에 대해서  (0) 2013.05.31
lower_bound와 upper_bound  (0) 2013.05.30
pair의 크기 비교 방식  (0) 2013.05.29