반응형
[C++] std::cin 사용 시 주의점
cin 변수의 타입불일치
코드를 짜다가 정수 값을 입력받을 일이 있었는데, 예상치 못한 에러가 나와서 당황했다.
아래와 같은 코드가 있다고 해보자.
#include <iostream>
int main(){
int index;
std::cout << "Enter index : ";
std::cin >> index;
std::cout << "index is " << index << std::endl;
int num;
std::cout << "Enter num : ";
std::cin >> num;
std::cout << "num is " << num << std::endl;
return 0;
}
올바른 정수값을 넣어 줄 경우 출력은 생각하는 대로다.
만약 문자를 입력한다면 어떻게 될까
두번째 입력을 받기도 전에 채워지고 이상한 값이 num 에 할당된다.
문제의 원인
- 타입 불일치: int 변수에 문자를 입력하면, 입력 스트림은 실패 상태로 설정된다. 이 때문에 변수 index는 초기화되지 않거나 기본값인 0으로 설정된다.
- 스트림의 실패 상태: 입력이 실패하면 스트림이 실패 상태에 머물게 된다. 이 상태에서는 더 이상의 입력을 받지 않으며, 스트림을 명시적으로 클리어하지 않는 한 이 상태가 유지된다.
- 버퍼 내 데이터: 문자 데이터가 입력 버퍼에 남아 있어 다음 입력 호출에 영향을 준다.
해결방법
먼저 올바르지 않은 cin 이 입력되는 상황이 예상되는 부분마다 검사를 해준다.
while ( std::cin.fail() ){ // If wrong cin
std::cin.clear; // clear the error status flag
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // clear the buffer
std::cout << "Enter index : ";
std::cin >> index;
}
- std::cin.fail() 함수는 입력이 실패했을 때 true를 반환한다.
- std::cin.clear() 함수로 오류 상태 플래그를 clear 한다.
- std::cin.ignore() 함수는 두개의 매개변수를 받는다
- 최대 문자 수 (기본값: 1): 스트림에서 무시할 최대 문자 수를 지정한다. 타입은 std::streamsize 다.
- climits 헤더를 사용할 경우, INT_MAX 를 사용하도 되는데 (int 의 최대값), 플랫폼에 따라 타입 불일치 문제가 발생할 수 있으므로 limits 헤더의 std::numeric_limits<std::streamsize>::max() 를 쓰는 것이 안전하다.
- 구분자 (기본값: EOF): 이 구분자를 만날 때까지 문자를 무시하고, 구분자 자체도 무시한다.
- 최대 문자 수 (기본값: 1): 스트림에서 무시할 최대 문자 수를 지정한다. 타입은 std::streamsize 다.
결과
반응형
'SW > C,C++' 카테고리의 다른 글
[C/C++] 함수인자로써 이중포인터와 가변길이배열 (0) | 2024.05.13 |
---|---|
[C++] 배열 index 관련 예외처리 (0) | 2024.05.03 |
[C/C++] 커널 드라이버에서의 함수포인터 (0) | 2024.04.22 |
[C/C++] 콜백함수의 인자로써 void 포인터 (0) | 2024.04.21 |
[C/C++] 이중포인터와 void 포인터 (0) | 2024.04.20 |
댓글