입력 스트림은 하나씩 문자를 구문 분석합니다. 숫자 추출의 경우 스트림은 숫자가 아닌 문자를 찾을 때까지 문자를 계속 읽습니다. 이미 피연산자에 문자를 성공적으로 쓴 경우 및 숫자가 아닌 문자를 읽으려는 시도가없는 경우 std::ios_base::failbit
을 설정하지 않습니다. 따라서 std::cin.good()
은 첫 번째 반복에 대해 true
을 반환합니다.
일반적으로 good()
을 검사하는 것이 스트림 유효성 평가의 바람직한 방법이 아닙니다. 스트림에는이 작업을 수행하는 내부 불린 연산자가 있습니다. 당신이해야 할 모든 부울 식에 실제 입력 작업을 둘러싸입니다 :
if (std::cin >> option) {
// successful input
}
else {
// unsuccessful
}
을 이제 전체 입력이 숫자인지 확인하기 위해서는 문자열로 읽고 수동 구문 분석을 수행하는 가장 좋은 것입니다 스트림은 자체적으로이 작업을 수행 할 수 없으므로 (기본적으로) 또는 스트림 자체에서이 작업을 수행하도록하려면 입력이 전적으로 숫자가 아닌 것으로 판단 할 수있는 경우 오류 마스크를 설정하는 사용자 정의패싯을 생성 할 수 있습니다. 이 패싯은 스트림의 로케일에 설치됩니다.
class num_get : public std::num_get<char>
{
public:
iter_type do_get(iter_type it, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long& v) const
{
auto& ctype = std::use_facet<std::ctype<char>>(str.getloc());
it = std::num_get<char>::do_get(it, end, str, err, v);
if (it != end && !(err & std::ios_base::failbit)
&& ctype.is(ctype.alpha, *it))
err |= std::ios_base::failbit;
return it;
}
};
원하는 동작을 얻을 수있는 스트림으로 로케일과 imbue()
에 로케일을 설치한다 : : 원래로 변경하여 언제든지 제거 할 수 있습니다
std::locale original_locale(std::cin.getloc());
std::cin.imbue(std::locale(original_locale, new num_get));
if (std::cin >> option) {
// input was entirely numeric
}
else {
// input was not entirely numeric
}
을 난 당신이 오류가 의심 이 코드에 대해 두 번 메시지 아마도''임의의 문자를 입력하십시오 ... ''와''Invalid input!''을 한 번 보았을 것입니다. 그것이 코드를 재현 할 때 얻는 것입니다. – 0x499602D2
그 이유는 숫자 입력을 추출 할 때 스트림이 전체 문자 시퀀스를 구문 분석하지 않기 때문입니다. ''123 ''부분과 같이 충분합니다. 입력 "abc"의 두 번째 부분은 다음 추출을 위해 여전히 남아 있습니다. 따라서 첫 번째 반복에서'cin.good()'는'true'입니다. – 0x499602D2
또한 C++ 11에서 추출에 실패한 후에'option'을'0'으로 간주 할 수 있습니다. 해당 가정을 수행하기 전에 컴파일러가이를 지원하는지 확인하십시오. 컴파일러 버전
0x499602D2