알고리즘 문제를 풀면서 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 하기' 포스트를 참조 바란다.
'개발자의 길' 카테고리의 다른 글
[Design pattern] 추상 팩토리 패턴 ( Abstract Factory pattern ) (1) | 2020.09.15 |
---|---|
[Design pattern] 팩토리 메서드 패턴 ( Factory method pattern ) (0) | 2020.08.30 |
[C++] C++에서 string 문자열을 받아와 split 하기 (0) | 2018.09.15 |
[Java, Android] Date, Calendar 클래스를 이용해 시간 표현하기 (0) | 2018.09.02 |
[Data Structure] Binary Search Tree - 이진 탐색트리 (0) | 2018.05.17 |