개발자의 길

[C++] C++에서 문자열 줄단위로 받기

토아드 2018. 9. 29. 23:51
반응형


 알고리즘 문제를 풀면서 Input을 벡터 파라미터로 주는것이 아니라 문자열로 주는 경우, 또는 문자열 자체를 처리하는 알고리즘인 경우에 C++로 풀어야 되는경우, 익숙하지 않으면 문자열을 읽는 부분에서부터 문제점이 생긴다.


Input 

4

2 3 4 5 6 8 

2 4 1 2 3

1 1 2 3

1 1 4


*첫번째 값은 줄 수 N, 그다음부터 N개의 줄에 랜덤한 갯수의 값들이 들어온다.


 위와같이 문자열이 주어지면 C++ 초보자의 입장에서 처리하기가 난감하다. cin 으로 처음 표준입출력을 배운 경우 공백과 개행문자를 무시해버리는 특성 때문에 어떻게 현재 라인을 구분해야할지 잘 모르게 되고, 다른 방법을 찾아보면서 getline() ,cin.getline() 등의 함수를 찾아보게 되는데 왜 또 그렇게 사용법은 많고 파라미터를 요란하게 넣어야 하는건지.. 그래서 이번에 제대로 정리해 보기로 했다.


 이번 포스트에서는 '표준 입출력'으로 '문자열을 줄 단위로 받는 방법'을 소개하고자 한다.


 *이 포스트는 '[C++] C++에서 string 문자열을 받아와 split 하기' 포스트의 내용을 포함하고 있습니다


 getline(string) 이용

 

 getline은 1) std::getline 함수와 2) std::istream::getline 함수 두가지가 존재한다.

 

 후자의 경우 최대로 받을 수 있는 문자길이를 입력하는 등 고려할 사항이 있지만, 전자의 경우는 어떤 string 변수에 값을 넣을지만 고려해 주면 되니 편하다.


 위 Input 이 들어올 때 아래 코드와 같이 작성이 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int n;
cin >> n;
string line;
//cin은 개행문자 전까지 읽고 처음에 나오는 개행문자는 무시
//getline은 개행문자까지 읽고 처음에 나오는 개행문자도 읽음
//그러므로 cin으로 처음값 N을 읽고 난 후 개행문자를 읽어주는 getline을 한번 호출 해 줘야 된다 
getline(cin, line);
for (int i = 0; i < n; i++){
    //\n이 나올 때 까지 읽기 (한줄 읽기)
    getline(cin, line);
    //한 줄 읽은 뒤 ' ' 을 기준으로 split
    istringstream ss(line);
    string buffer;
    while (getline(ss,buffer,' ')) {
        //' ' 문자가 나올 때까지 읽는다.
        int value = atoi(buffer.c_str());
        //... 받은 value를 처리...
    }
}    
cs


 여기서 주의해야 할 점은 getline은 개행문자 까지 읽지만 cin은 개행문자 전까지 읽는다는 점이다.


 cin로 한번 읽고 난 다음 getline로 읽으면 4를 읽고 \n이 남아있는 상태라서 getline을 한번 더 수행해 줘야 된다. 그 다음부터 getline을 실행해야 원하는 대로 값을 넣을 수 있다. 아니면 처음부터 getline으로 값을 읽어줘도 된다.


 한줄 읽고 난 뒤 읽은 스트링을 split 하는 방법은  '[C++] C++에서 string 문자열을 받아와 split 하기'  포스트를 참조 바란다.

반응형