-
[C++] cin.ignore와 버퍼에 대한 이해Programming 기초/C++ 2024. 6. 28. 19:31
cin
cin은 character input의 약자로, 버퍼의 값을 읽어온다. 만약 버퍼에 읽어올 값이 없으면 표준입력스트림으로부터 입력을 받아와 버퍼에 저장하고나서 버퍼의 값을 읽어온다.
입력을 받는다는 것이 아닌 버퍼를 먼저 읽으려고 한다는 관점이 중요하다.
(버퍼는 자료구조 queue와 유사하다. 선입선출로 작동한다.)
- 'cin >>' 은 공백(스페이스, 탭, 줄바꿈)문자를 기준으로 끊어서 읽어오고, 공백문자는 무시한다.
#include <iostream> using namespace std; int main() { char name[100]; cout << "이름을 입력해주세요. : "; cin >> name; cout << "이름 : " << name << endl; return 0; } /* --------------terminal--------------- 이름을 입력해주세요. : john nanana --------------output----------------- 이름 : john */
0. 버퍼에 다음과 같이 저장된다. [ j ] [ o ] [ h ] [ n ] [ ' ' ] [ n ] [ a ] [ n ] [ a ] [ n ] [ a ] [ '\n' ]
1. 여기서 name에 [ j ] [ o ] [ h ] [ n ] 가 저장된다.
- cin 을 두 번 연달아 사용할때, 공백 문자를 기준으로 잘라서 읽어오기 때문에 공백문자를 사용해서 한 번의 입력으로 두 번 입력할 수 있다.
#include <iostream> using namespace std; int main() { char name1[100]; char name2[100]; cout << "이름을 입력해주세요. : "; cin >> name1; cin >> name2; cout << "이름1 : " << name1 << endl; cout << "이름2 : " << name2 << endl; return 0; } /* --------------terminal--------------- 이름을 입력해주세요. : john nanana --------------output----------------- 이름1 : john 이름2 : nanana */
0. 버퍼에 다음과 같이 저장된다. [ j ] [ o ] [ h ] [ n ] [ ' ' ] [ n ] [ a ] [ n ] [ a ] [ n ] [ a ] [ '\n' ]
1. 이름 1 에 [ j ] [ o ] [ h ] [ n ] 가 저장되고
2. 버퍼에는 [ ' ' ] [ n ] [ a ][ n ] [ a ] [ n ] [ a ] [ '\n' ]가 남는다.
3. 이후 이름 2에 남은 문자가 저장되는데, 버퍼에 첫 번째로 남겨진 공백(' ')은 무시하고[ n ] [ a ][ n ] [ a ][ n ] [ a ] 가 저장된다.
4. 최종적으로 버퍼에는 [ '\n' ]가 남는다.
cin.ignore( n, delim)
: cin.ignore는 버퍼에 저장된 데이터를 조건에 맞게 clear한다. 만약 버퍼에 이스케이프 문자외의 clear할 문자가 부족할 경우 표준입력스트림으로부터 입력을 받아서 버퍼에 저장하고 clear를 수행한다.
(아래 코드를 볼 때 두 번째로 입력 받는 위치를 주의깊게 보자.)
- 첫 번째 매개변수 n은 무시할 최대 문자 개수를 의미한다.
- 예를들면 매개변수1의 값으로 5가 지정된다면, 버퍼에 저장된 데이터를 순차적으로 5byte를 무시(clear)한다는 의미이다.
#include <iostream> using namespace std; int main() { char name1[100]; char name2[100]; cout << "첫 번재 이름을 입력해주세요. : "; cin >> name1; cin.ignore(5) cout << "두 번째 이름을 입력해주세요. : "; cin >> name2; // 여기서 두 번째 입력을 받음 cout << endl ; cout << "이름1 : " << name1 << endl; cout << "이름2 : " << name2 << endl; return 0; } /* --------------terminal--------------- 첫 번재 이름을 입력해주세요. : john nanana 두 번째 이름을 입력해주세요. : --------------output----------------- 이름1 : john 이름2 : na */
cin.ignore은 공백문자를 모두 카운트하므로 주의해야한다.
1. 이름 1에 [ j ] [ o ] [ h ] [ n ] 을 저장하고 난 뒤에
2. 버퍼에 남은 [ ' ' ] [ n ] [ a ] [ n ] [ a ] [ n ] [ a ] [ '\n' ] 에서 앞의 공백을 포함해서 5문자를 무시하고,
3. 이름 2에 남은 [ n ] [ a ] 를 저장한다.
4. 최종적으로 버퍼에는 [ '\n' ] 가 남는다.
#include <iostream> using namespace std; int main() { char name1[100]; char name2[100]; cout << "첫 번재 이름을 입력해주세요. : "; cin >> name1; cin.ignore(8); // 여기서 두 번째 입력을 받음 cout << "두 번째 이름을 입력해주세요. : "; cin >> name2; cout << endl ; cout << "이름1 : " << name1 << endl; cout << "이름2 : " << name2 << endl; return 0; } /* --------------terminal--------------- 첫 번재 이름을 입력해주세요. : john nanana apple mango 두 번째 이름을 입력해주세요. : --------------output----------------- 이름1 : john 이름2 : apple */
위와같이 cin.ignore(n)의 n을 버퍼에 남은 7문자를 초과하게 설정하면, 에러를 발생시키는 것이 아닌 추가로 입력을 받고, 추가된 버퍼에서 무시할 남은 문자 개수만큼 무시(clear)한다.
...
1. 이름 1에 [ j ] [ o ] [ h ] [ n ] 가 저장되고, 버퍼에는[ ' ' ] [ n ] [ a ][ n ] [ a ][ n ] [ a ] [ '\n' ]가 저장된다.
2. cin.ignore(8)가 실행된 직후에 버퍼에는 [ '\n' ]만 남고, 문자 하나를 더 clear해야 하므로 추가로 입력을 받는다.
3. 예시로, apple mango를 추가 입력. 버퍼에는 [ '\n' ] [ a ] [ p ] [ p ] [ l ] [ e ] [ ' ' ] [ m ] [ a ] [ n ] [ g ] [ o ] [ '\n' ]가 저장됨.
5. 남은 1문자를 제거한다. 버퍼에는 [ a ] [ p ] [ p ] [ l ] [ e ] [ ' ' ] [ m ] [ a ] [ n ] [ g ] [ o ] [ '\n' ]가 남아있다.
6. cin >> name2 는 버퍼에서 [ a ] [ p ] [ p ] [ l ] [ e ] [ ' ' ] 를 끊어서 읽어오고 name2에 저장한다.
7. 최종적으로 버퍼에는 [ ' ' ] [ m ] [ a ] [ n ] [ g ] [ o ] [ '\n' ] 가 남는다.
- 두 번째 매개변수 delim은 무시를 중단할 종료 문자이다.
- 예를들어 delim = '\n'이라면, 개행문자를 만나기 전의 버퍼의 모든 값과 개행문자를 모두 무시(clear)한다.
#include <iostream> using namespace std; int main() { char name1[100]; char name2[100]; cout << "첫 번재 이름을 입력해주세요. : "; cin >> name1; cin.ignore(8, '\n'); // '\n'을 추가 // cin.ignore(numeric_limits<streamsize>::max(), '\n'); 와 결과 동일 cout << "두 번째 이름을 입력해주세요. : "; cin >> name2; // 여기서 두 번째 입력을 받음 cout << endl ; cout << "이름1 : " << name1 << endl; cout << "이름2 : " << name2 << endl; return 0; } /* --------------terminal--------------- 첫 번재 이름을 입력해주세요. : john nanana 두 번째 이름을 입력해주세요. : apple mango --------------output----------------- 이름1 : john 이름2 : apple */
cin.ignore(8, '\n')로 종료 문자를 지정해주면, 7문자를 무시하고나서 8번째 '\n'문자를 만나서 '\n'을 포함해서 무시(clear)해준다.
...
1. 이름 1에 [ j ] [ o ] [ h ] [ n ] 가 저장되고, 버퍼에는[ ' ' ] [ n ] [ a ][ n ] [ a ][ n ] [ a ] [ '\n' ]가 저장된다.
2. cin.ignore(8, '\n')가 실행된 직후에 버퍼는 비어진다.
3. 예시로, apple mango를 추가 입력. 버퍼에는 [ '\n' ] [ a ] [ p ] [ p ] [ l ] [ e ] [ ' ' ] [ m ] [ a ] [ n ] [ g ] [ o ] [ '\n' ]가 저장됨.
4. cin >> name2 는 버퍼가 비어있으므로 표준입력 스트림으로부터 입력("apple mango")을 받고 버퍼에 저장한다.
5. 이후 [ a ] [ p ] [ p ] [ l ] [ e ] 를 name2에 저장한다.
6. 최종적으로 버퍼에는 [ ' ' ] [ m ] [ a ] [ n ] [ g ] [ o ] [ '\n' ] 가 남는다.
'\n'를 포함해서 무시(clear)해주는 것에 주의하자.
예를들어 위 코드에서 만약 cin.ignore(7)로 대체한다면 최종적으로 버퍼에는 [ '\n' ]이 남지만
원래코드대로 cin.ignore(8, '\n')을 수행하면 최종적으로 버퍼는 텅 비어있게 된다.
'Programming 기초 > C++' 카테고리의 다른 글
c++ 백준 1676번 팩토리얼의 0의 개수 (0) 2024.08.20 STL 컨테이너 (0) 2024.08.11 [c++] vscode에서 c++ 설치 the prelaunchtask c/c++: gcc build active file terminated with exit code -1 에러 해결 (0) 2024.07.19 [c++] 참조자형식 "&" (0) 2024.07.19