백준 11718번(boj.kr/11718) 그대로 출력하기 문제를 getline으로 풀다가 C style string이랑 C++ string 클래스 쓰는 방식이랑 C 함수랑 문법이 헷갈려서 찾아보았다. 생각해 보면 getline은 항상 쓸 때 마다 문법이 헷갈려서 찾아보게 된다. 은근히 자주 안 써서 그런가... 이런건 파이썬으로 하면 그냥 input() 쓰면 돼서 참 쉬운데 이런 부분만 봐도 여러 기능이 덕지덕지 붙어있는 C++의 특징이 보인다. 쓸 때마다 매번 헷갈려서 이번 기회에 정리해 보았다.
1. C style string(char 배열)에 입력받는 방법
주어진 문제에서는 조건이 100글자 이하로 제한되어 있어 굳이 string 클래스를 쓰지 않고 C style string으로 처리했다.
이 경우에는 istream::getline() 함수를 사용한다.
istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );
// 예시
const int kStudentIdLength = 10;
char student_id[kStudentIdLength + 1];
cin.getline(student_id, kStudentIdLength + 1);
쉽게 말하면 cin.getline() 형태로 쓰는 방식이다. C style string에서는 cin.getline( 입력받을 char배열, 스트림 사이즈 ) 이렇게 쓰면 된다. 참 웃긴게 C style string이랑 호환이 잘 되는 string class는 이러면 또 안 된다...
streamsize는 character 자료의 개수를 입력하면 된다. 보통은 입력받을 char 배열의 사이즈를 넣으면 된다. 이 때 주의할 점은 C style string이므로 맨 마지막에 null 문자('\0')를 포함한 개수라는 점이다. 즉, char 배열 사이즈를 실제 입력받을 문자 +1 로 정의하고, getline으로 입력받을 때도 실제 입력받을 문자 개수 +1 로 streamsize를 지정해야 한다.
delim 파라미터로 '\n' 이외의 구분자도 지정할 수 있다.
주어진 문제는 다음과 같이 풀었다.
#include <iostream>
using namespace std;
int main(){
const int kInputLength = 100;
char input[kInputLength + 1];
while(cin.getline(input, kInputLength + 1)) {
cout << input << endl;
}
}
while에 getline 함수를 통째로 넣어도 end of file이 되었을 때 잘 종료된다. istream::getline()의 return은 *this (여기서는 cin)로 istream 객체이나 클래스 내부에서 연산자 오버로딩을 잘 정의해 놓았기 때문에 객체의 eof flag가 set되어 있으면 false를 return하는 방식으로 while문을 탈출할 수 있다.
2. string 객체에 입력받는 방법
입력받을 공간이 string 객체인 경우이다. 프로젝트를 할 때는 string 객체가 char 배열보다는 너무너무 편하기 때문에 이 방식을 자주 쓸 것 같다. 이 때는 std::getline()을 사용한다. string 헤더를 include하면 딸려 오는 녀석이다.
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
...
#include <string>
...
// 예시
string student_id;
getline(cin, student_id);
string 객체는 cin.getline() 형태로는 입력받을 수 없다. std::getline()을 써야 하는데 이 때 getline은 이름만 같고 string 헤더에서 딸려 오는 함수라고 생각하자. 이 때에는 istream, 주로 cin이 getline의 첫 번째 파라미터로 들어간다. string 클래스는 길이 제한이 사실상 없기 때문에 버퍼 사이즈는 지정해 줄 필요가 없다. 그 외에는 istream::getline()과 비슷하게 사용하면 된다.
주어진 문제를 string 클래스를 이용해 풀면 다음과 같다.
#include <iostream>
#include <string>
using namespace std;
int main() {
string input;
while(getline(cin, input)) {
cout << input << endl;
}
}
출처 : cplusplus.com
'C++' 카테고리의 다른 글
[C++] std::string 클래스가 std::list보다 느릴 수 있는 이유 (0) | 2020.02.06 |
---|