본문 바로가기

programming/문제 해결

[C++, 코딩 테스트] 문자열을 입력 받고 문자로 추출, 공백으로 구분하기 - (getline() 함수 사용시 주의할 점)

반응형

1. 개요

 

 최근 알고리즘 테스트에 현타란 현타를 강하게 맞아서 '나동빈'님의 책인 '이것이 취업을 위한 코딩테스트다.' 라는 책을 통해 체계적으로 공부중이다. 그중 구현 단원에서 문자열에 관한 C++문법을 정리해봐야 겠다는 생각이 들어 글을 쓰게 되었다. 예제 4-1의 상하좌우 문제이다.

 

2. 이론

 

 String자료형은 매번 문자형의 배열을 사용하던 나에게는 신세계이자 구원자였다. 그러나 C++도 결국 C계열인지 메모리와 같은 부분을 신경써야 한다는 것을 뼈저리게 느끼는 중이다. 그래도 C에 비하면 심각하게 어려운 것이 아니니 관련 자료를 찾으며 공부하였다. 이번 글에서는 C++에서 문자열을 입력받고 이를 문자로 추출할때, 그리고 버퍼를 비우는 방법에 대해 작성할 것이다.

 

3. 예시 코드

 

- 문자열에서 문자 추출

 

 가장 기본적인 문법인 문자 추출이다. 이는 stringstream 객체를 활용하여 구현한다. 다음 코드를 보자.

 

#include <iostream>
#include <sstream>

using namespace std;

int main(void) {

	stringstream ss;
	string str = "abcdefg";
	char buff;

	ss.str(str);

	while (ss >> buff)
		cout << buff << endl;

	return 0;
}

 

 이렇게 stringstream을 사용하면 문자정도는 간단하게 추출할 수 있다. 다음은 실행 결과이다.



- 정수가 포함된 문자열에서 문자 추출

 

 그럼 문자열에 문자가 아닌 정수가 있어도 잘 추출 할 수 있을까? 다음 코드를 보자.

 

#include <iostream>
#include <sstream>

using namespace std;

int main(void) {

	stringstream ss;
	string str = "ab1c2d5e-9f1.5g";
	char buff;

	ss.str(str);

	while (ss >> buff)
		cout << buff << endl;

	return 0;
}

 

 실행 결과를 보면 바로 알겠지만, string안에서 정수 또한 하나의 문자이기에, 다음과 같이 출력된다.



- 공백이 포함된 문자열에서 문자 추출

 

 자, 그럼 공백이 포함된 문자열을 보도록 하자. 공백을 제외하고 문자가 하나씩 추출될까? 다음 코드와 실행 결과를 보자.

 

#include <iostream>
#include <sstream>

using namespace std;

int main(void) {

	stringstream ss;
	string str = "a b c d e f g h i j k";
	char buff;

	ss.str(str);

	while (ss >> buff)
		cout << buff << endl;

	return 0;
}


 다행이도 공백은 제외하고 문자를 추출 하는 것을 볼 있다. 이제 문자열을 한줄 읽고 문자를 하나씩 출력하는 코드를 작성해보자.

 

- 문자열 한줄을 입력받고 string 객체에 저장하기

 

 getline함수를 사용해 string객체 변수에 문자열 한 줄을 입력받을 수 있다. 다음 코드를 보자.

 

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

using namespace std;

int main(void) {

	stringstream ss;
	string str;
	char buff;

	getline(cin, str);

	ss.str(str);

	while (ss >> buff)
		cout << buff << endl;

	return 0;
}

 

 이렇게 하면 문자열 한줄을 입력받고 해당 문자열에서 공백을 제외한 문자를 하나씩 추출할 수 있다. 다음은 실행 결과이다.



- getline()함수 사용시 주의할점

 

 getline()함수는 버퍼에 있는 내용을 전부 가지고 오는 함수이다. 버퍼가 뭔지 궁금하다면 해당 블로그에 버퍼와 관련된 글이 있으니 읽어보길 바란다.

 

https://apape1225.tistory.com/10?category=817168 

 

[C언어, C++] scanf() 문자 입력 문제 - 입력 버퍼

1. 개요 이 카테고리는 내가 겪은 문제들, 그리고 이 문제들을 해결하는 과정을 정리하고자 만든 카테고리이다. 사실 엄청난 문제들도 아니다 ㅎㅎ 사소한 문제가 대부분이지만, 때론 사소한 문

apape1225.tistory.com

 

 일단 다음 코드와 실행 결과를 보며 생각해보자.

 

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

using namespace std;

int main(void) {

	stringstream ss;
	string str;
	char buff;
	int N;

	cin >> N;
    
	getline(cin, str);

	cout << N << endl;
	cout << str;

	return 0;
}

 

 해당 코드를 보면 정수 N을 입력받고 문자열 str 한줄을 입력받아 이 둘을 각각 출력해주는데, 원하는 데로 작동하지 않는다. 다음은 실행결과이다.



 정수만이 입력되고 정수만이 출력된 것이다. 왜 그런 것일까? 이유는 버퍼가 완전하게 비워지지 않았기 때문이다. 결국 우리는 온전한 문자열이 입력될 수 있도록 버퍼를 비워줘야 한다. 다음 코드를 보자.

 

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

using namespace std;

int main(void) {

	stringstream ss;
	string str;
	char buff;
	int N;

	cin >> N;

	cin.ignore();

	getline(cin, str);

	cout << N << endl;
	cout << str;

	return 0;
}

 

 해당 코드를 보면 cin.ignore(); 메소드를 사용해 버퍼를 비워준 후 문자열을 입력받는 것을 확인할 수 있다. 이렇게 코드를 작성하면 정상적으로 작동되는 코드를 볼 수 있다. 다음 실행 결과를 보자.



 

반응형