티스토리 뷰
[C++] 표준 입력함수와 입력버퍼 관리 : cin / cin.getline / getline / cin.get / cin.fail / cin.clear / cin.ignore
그레고리 2022. 2. 3. 19:23cin
사용방법은 다음과 같다.
int a;
cin >>a;
- <iostream>라이브러리에 속한 함수.
- 표준 입력 버퍼에서 공백문자, 개행문자('\n') 이전까지의 값을 받아온다.
- 쉽게 말해서 개행과 공백이 포함된 문자열은 받아올 수 없다.
- 공백이후의 값 및 개행 문자는 입력 버퍼에 남겨둔다.
- 포인터 변수를 통해 배열을 받아올 수는 없다.
int a[3];
int *b = new int[3];
cin >> a; //가능
cin >> b; //불가능
cin >> b[i]; // 가능
다음과 같은 상황에서 a에 공백이 포함된 문자열을 넣어보자.
char a[10];
char b[10];
cin >> a;
cin >> b;
1 .여기서 a에 'hello world' 라고 입력하면 a에는 'hello' 까지만 들어간다.
2. 입력버퍼에 'world'가 남아있는 상태에서 b에 입력을 받는다.
3. 입력버퍼에 'world'가 남아있으므로 내 입력을 무시하고 바로 b에 'world'가 들어간다.
뒤에서 다음입력을 받기 전에 입력버퍼를 비워주는 함수와 띄어쓰기가 포함된 문장을 입력받는 함수를 설명하겠다.
cin.getline()
사용방법은 다음과 같다.
cin.getline(char* str, n);
cin.getline(char* str, n, char dlim);
// 예시
char a[5];
char* b[5];
cin.getline(a,6);
cin.getline(b,6);
- <istream>라이브러리에 속한 함수.
- 문자 배열을 받는데 사용한다.
- n-1개의 문자를 읽어와 저장하고, n번째 문자는 NULL('\0')을 넣는다.
n개의 문자를 입력했다면 n-1개만 읽어오고, 남은 한개는 입력버퍼에 남아있다. cin에서 봤던 것 처럼 이 상태에서
버퍼를 비우지 않고 다음 입력을 받으면 입력 버퍼에 남아있던 문자가 그대로 들어간다.
- dlim은 제한자 문자로, 지정해주면 해당 문자 직전까지 읽는다. 지정하지 않으면 자동으로 '\n'으로 처리된다.
cin과 마찬가지로 배열에 초과 입력을 해도(길이가 5인 char 배열에 n을 10으로 해서 입력을 받아도) 컴파일 단계에서는 오류를 볼 수 없다. cin의 경우 배열에 초과입력을 하면 별다른 오류 없이 일단 메모리에 저장이 된다. 대신 초과 입력된 데이터들이 의도하지 않은 메모리에 저장되어서 문제를 일으킬 수 있다. 어쨌든 초과 입력을 해도 해당 배열을 출력해보면 입력한 값이 모두 다 찍혀 나온다. 이것은 cin.getline()도 마찬가지이다. 단 n을 배열 사이즈에 맞게 설정해주면 아무리 초과 입력을 해도 딱 n-1개까지만 읽어온다.
getline()
사용방법은 다음과 같다.
getline(cin, string str);
getline(cin, string str, char dlim);
//예시
string str;
getlien(cin,str);
- <string>라이브러리에 속한 함수.
- cin.getline()과 유사하지만 char 배열 변수가 아니라 string 변수에 입력을 할 때 사용한다.
- cin.getline()과 다르게 최대 입력 가능한 문자수를 따로 지정하지 않는다.
cin.get()
사용법은 다음과 같다.
char a;
a = cin.get();
- 입력 버퍼에서 문자를 하나만 가져온다. 하나 이상 입력된 경우 나머지는 입력버퍼에 남겨둔다.
- 공백, 개행문자도 입력으로 친다.
cin.ignore()
지금까지 본 입력 함수들이 입력 버퍼에 무엇을 남기는지 정리하면
cin
- 공백이 있는 문자열을 입력했을 경우 : 공백문자부터 개행문자까지
- 공백이 없는 문자열을 입력했을 경우 : 마지막 개행문자
cin.getline()
- 제한자 문자 이후부터 개행 문자까지 (제한자 문자는 포함하지 않는다.)
- n번째 문자부터 개행문자까지
getline()
- 제한자 문자 이후부터 개행 문자까지 (제한자 문자는 포함하지 않는다.)
cin.get()
- 입력된 첫번째 문자를 제외한 모든 문자.
이렇게 볼 수 있다.
문제는 연속해서 입력 함수들을 사용하면 앞에서 사용했던 입력함수가 입력 버퍼에 남겨놓은 데이터들을 그 다음 입력함수들이 읽어버린다. 그러면 내 입력을 무시하고 바로 엉뚱한 값을 변수에 저장해버린다.
이런 상황을 막기 위해 입력함수를 사용한 후에 바로 입력 버퍼를 비워주는 것이 안전하다.
cin.ignore()은 입력버퍼를 비워주는 함수로, 사용방법은 아래와 같다.
//사용방법
cin.ignore(int n, char dlim);
//예시
char ch;
string str;
cin >> ch;
cin.ignore();
getline(cin,str);
- 입력 버퍼를 비운다.
- n개를 읽어들여서 버리거나 제한자 문자 까지 읽어들여서 버린다. 정의하지 않으면 입력버퍼를 싹 비운다.
cin.fail() , cin.clear()
c++에서 문자가 아닌 숫자는 모두 입력 버퍼 필요없이 바로 변수에 저장된다.
(숫자를 입력받을 수 있는 것은 cin 뿐이다. get붙은것들은 문자만 받는다. int형 변수에 쓰면 아스키값이 들어갈 것이다.)
만약 int변수에 문자를 넣게 되면 cin에러가 발생하기 때문에 cin 에러 플래그값이 1로 세팅된다. (잘못 입력한 문자는 입력 버퍼에 그대로 남아있다.)
cin.fail()은 위와 같이 cin 오류가 발생하면 true를 리턴한다. 우리는 fail()로 오류상황을 파악할 수 있다.
int a;
char ch;
cout << "input a: ";
cin >>a;
if(cin.fail()){
cout >> "error" >>endl;
}
cout << "input ch: ";
cin >> ch;
cout << "a: "<< a <<endl;
cout << "ch: "<< ch <<endl;
위와 같은 코드에서 cin >> a에 'h'를 입력하면 에러 플래그값이 1로 세팅되고, cin.fail()이 true를 반환할 것이다. 그럼 cin >> ch; 는 제대로 동작할 수 있을까?
아니다. ch 입력을 무시하고 바로 cout<<a; 가 실행된다. 심지어 버퍼에 남아있는 'b'가 ch에 들어오지도 않았다.
이것은 내부 상태 플래그값이 1 여전히 1이기 때문에 그렇다. 따라서 cin오류가 있어도 그 다음 동작을 문제 없게 하기 위해서는 cin.clear()함수를 통해 플래그값을 초기화 시켜줄 필요가 있다.
위의 코드에서 cin.clear()을 추가하고 실행해보자.
if(cin.fail()){
cout >> "error" >>endl;
cin.clear();
}
아직 정상적으로 작동하지는 않는다. 여전히 cin >> ch;는 무시된다. 그러나 이것은 버퍼에 남아있는 'b'가 들어갔기 때문에 무시된 것이다. 따라서 위에서 배운 버퍼 비우는 함수 cin.ignore()까지 써주자.
if(cin.fail()){
cout >> "error" >>endl;
cin.clear();
cin.ignore();
}
이제 정상적으로 ch에 대한 입력을 받을 수 있다!
'C++' 카테고리의 다른 글
[C++] std::ios_base::sync_with_stdio(false); (0) | 2022.02.16 |
---|---|
[C++] 직접 정의한 헤더파일 사용해보기 (네임스페이스와 클래스) (0) | 2022.02.11 |
[C++] 헤더 파일과 네임스페이스 (0) | 2022.02.09 |
[C++] 배열 초기화하는 방법 (0) | 2022.02.03 |
[C++] 배열 초과 입력에 관하여 (0) | 2022.02.02 |
- Total
- Today
- Yesterday
- QO
- 버추얼박스
- mac unity vscode autocomplete
- VS Code
- Unity
- Query
- 컨셉때문에킹받으셨나요..죄송합니다..제가 봐도 킹받네요
- ()
- 트리
- Winform
- Unity vs code
- androidstudio
- multiple Column
- gridContorl
- VirtualBox
- DevExpress
- =
- apt-get
- GIT
- apt
- Mac
- mac Unity vscode 자동완성
- Flutter
- flutterdoctor
- ubuntu
- Tree
- 해마코딩
- select
- DataSource
- 우분투
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |