2012-11-08 1 views
7

정수를 사용하는 프로그램이 있습니다. 사용자가 범위를 벗어난 번호 나 문자 등을 입력하면 프로그램이 붕괴되는 것을 어떻게 막을 수 있습니까?어떻게 cin을 살균합니까?

+4

http://www.parashift.com/c++-faq/istream-and-ignore.html – chris

답변

2

기억 경우 aswell 확인 후 버퍼를 삭제해야해야 참조하십시오. 입력 스트림은 요청 된 데이터를 스트림에서 추출 할 수없는 경우 복구 할 수있는 오류를 나타냅니다. 오류 비트를 확인하려면 std::basic_istream::fail() 메서드를 사용해야합니다. 오류가 발생하면 true을 반환하고 오류가 발생하면 false을 반환합니다. 오류가있는 경우 데이터가 스트림에 남아 있으며 물론 오류 비트도 std::basic_istream::clear()을 사용하여 지워야 함을 기억해야합니다. 또한 프로그래머는 잘못된 데이터를 무시해야합니다. 그렇지 않으면 다른 것을 읽으려는 시도가 다시 실패합니다. 이를 위해 std::basic_istream::ignore() 메서드를 사용할 수 있습니다. 유효한 값 범위는 수동으로 확인해야합니다. 좋아요, 충분한 이론은 여기에 간단한 예제가 있습니다 :

#include <limits> 
#include <iostream> 

int main() 
{ 
    int n = 0; 

    for (;;) { 
     std::cout << "Please enter a number from 1 to 10: " << std::flush; 
     std::cin >> n; 

     if (std::cin.fail()) { 
      std::cerr << "Sorry, I cannot read that. Please try again." << std::endl; 
      std::cin.clear(); 
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
      continue; 
     } 

     if (n < 1 || n > 10) { 
      std::cerr << "Sorry, the number is out of range." << std::endl; 
      continue; 
     } 

     std::cout << "You have entered " << n << ". Thank you!" << std::endl; 
     break; 
    } 
} 

희망이 있습니다. 행운을 빕니다!

2

뭔가 당신이 내가 cin의 기본 클래스 std::basic_istream 바로

if (cin.fail()) 
    { 
     cout<<"need to put a number"<<endl; 
     cin.clear(); 
     cin.ignore(); 
    } 
0

코드에 라이브러리를 추가하고 싶지 않으면 do..while() 문을 사용할 수도 있습니다. 을 입력하면 사용자 입력을 요청한 다음 변수에 수신 한 다음 while 부분에서 데이터를 계속 요청하지 않으면 예상되는 데이터인지 확인할 수 있습니다. 이미 언급 대답은 내가 문자열로 입력을 읽는 선호 적절하게

4

보다 더 많은 일을한다하더라도

또 다른 옵션 ..., 그리고 다음boost::lexical_cast<>로 살균 :

#include <boost/lexical_cast.hpp> 
#include <iostream> 
#include <string> 

int main() { 
    std::string s; 
    while(std::cin >> s) { 
    try { 
     int i = boost::lexical_cast<int>(s); 
     std::cout << "You entered: " << i << "\n"; 
    } catch(const std::bad_cast&) { 
     std::cout << "Ignoring non-number: " << s << "\n"; 
    } 
    } 
} 

추록 : 부스트에 알레르기가있는 경우이 lexical_cast 구현을 사용할 수 있습니다 :

template <class T, class U> 
T lexical_cast(const U& u) { 
    T t; 
    std::stringstream s; 
    s << u; 
    s >> t; 
    if(!s) 
    throw std::bad_cast(); 
    if(s.get() != std::stringstream::traits_type::eof()) 
    throw std::bad_cast(); 
    return t; 
} 
+0

다시 던지기가없는 캐치 올 조항은 아니오입니다. –

+0

설명하거나 인용문을 제공해 줄 수 있습니까? –

+0

@VladLazarenko : 수정 됨. –

0

당신은 INT에 유효한 입력의 간단하고 빠른 검사에 대한 다음과 같은 코드를 사용할 수 있습니다

#include "stdafx.h" 

#include <iostream> 
using namespace std; 

int main() 
{ 

    int intb; 
    while(!(cin>>intb)){ 
     cin.clear(); 
     cin.ignore (1000, '\n'); 
     cout<<"Invalid input enter again: "<<endl; 

    } 
    cout<<"The value of integer entered is "<<b<<endl; 

     return 0; 
} 

while 루프는 올바른 입력을 취득 할 때까지 반복에 유지합니다. cin.clear()는 오류 제어 상태를 변경합니다. cin.ignore()는 입력 스트림을 지우고 새 입력을 다시 가져올 수 있도록합니다. while 루프는 무한 상태가됩니다.

관련 문제