2011-02-01 5 views
3

잘못된 유형을 입력하면 내 cin 문을 '제거'하지 않는 방법을 알아야합니다.숫자를 요청했지만 사용자가 번호를 입력 할 때 갑자기 입력되는 루프를 방지하려면 어떻게합니까?

int mathOperator() 
{ 
    using namespace std; 

    int Input; 
    do 
    { 
    cout << "Choose: "; 
    el(); 
    cout << "1) Addition"; 
    el(); 
    cout << "2) Subtraction"; 
    el(); 
    cout << "3) Multiplication"; 
    el(); 
    cout << "4) Division"; 
    el(); 
    el(); 
    cin >> Input; 

    } 
    while (Input != 1 && Input != 2 && Input!=3 && Input!=4); 
    return Input; 
} 

는, 실행 예를 들어, 문자에 대한 입력 및 CIN 문이없는 것처럼 논스톱 연기 루프 : 코드는 여기에있다. 당신은 당신이

int i = (Input - 48); 
+2

나는 모든 사람이이 문제를 당분간 가지고 있다고 생각합니다. 그것을 통과 의례라고 생각해보십시오, 애쉴리. –

답변

2

잘못된 값으로 읽은 후 cin은 "실패"상태입니다. 이걸 다시 설정해야합니다.

오류 플래그를 지우고 버퍼를 비워야합니다. 따라서 :

cin.clear(); 
    cin.ignore(std::numeric_limits<streamsize>::max(), '\n'); 

두 번째 호출 "플러시"가있을 수 있습니다 데이터의 입력 버퍼는, 다음의 "CIN"호출을 준비하기합니다.

"코드 전체에 걸쳐"이 두 줄을 쓰는 경우 간단한 인라인 함수로 바꿀 수 있습니다.

inline void reset(std::istream & is) 
    { 
     is.clear(); 
     is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 

나는이 함수가 IStream을을 만든 있지만, 그것은 단지 사용자가 입력 무효 뭔가를 입력한다 cin을 위해 사용되는 대부분의 시간. 유효하지 않은 파일 또는 문자열 스트림 입력의 경우이를 수정할 방법이 없으므로 예외를 throw하는 것이 가장 좋습니다.

+0

numeric_limits 대신 뭔가를 넣으시겠습니까? 그렇다면, 무엇? 감사의 말 – LazerSharks

2
char Input; 

do 
{ 
// same code 
} 
while (Input != '1' && Input != '2' && Input != '3' && Input!='4'); 
return Input; 

[편집]

, 그래서 CIN은 어떤을 전달합니다 char 읽기 잘못된 문자

+0

고마워요, 그 생각은 없을 것입니다 : ChangeToNumber (char a)와 같은 기능을 가진 함수가 있으므로 너무 많이 다시 작성하지 않아도됩니다. 값에 의존하는 몇 가지 함수가 있습니다. 정수. –

+0

(int) (입력 - 48) 지금 내 대답을 편집 중입니다 –

+2

'48'을 직접 사용하는 것은 어리석은 아이디어입니다. 적어도 'Input-'0' '(그리고 심지어 당신이 읽은 캐릭터가'isdigit '과 함께 한 자릿수임을 보장 한 후에). –

2

int을 읽지 않는이 코드 조각을 사용할 수 있습니다 int로 문자를 변환하려면

+0

내 대답을 읽지 마십시오 :) –

+0

고맙습니다. –

+0

은 작동하지만 잘못된 cin을 재설정하는 방법을 사용자에게 알려주지 않습니다. – CashCow

0

나는 항상 int 형으로 캐스팅 할 수 있기 때문에이 문제가 왜 발생하는지, cin 입력이 int로 적용되지만 char이 입력되면 루프의 지속 시간 동안 입력 스트림에 유지되므로 이것이 사라지는 것처럼 보입니다.

자세한 내용은 : 당신이 입력이 적절한 형식 것에 대해 매우 특정 를 아니라면 http://www.daniweb.com/forums/thread11505.html

3

에서 Narue의 게시물을 참조, 당신은 거의 입력 스트림에서 직접 operator>>를 사용하고자합니다.

std::getline으로 줄을 읽고 std::istringstream에 넣고 거기에서 읽는 것이 더 쉽습니다. 실패하면 오류 메시지를 인쇄/기록하고 나머지 행을 버리고 (아마도) 다음 행으로 넘어갑니다. 그렇지 않은 경우

5

당신은 그 입력이 성공 확인하고 처리해야합니다 :

int mathOperator() { 
    using namespace std; 

    int Input; 
    do { 
    cout << "Choose: "; 
    el(); 
    cout << "1) Addition"; 
    el(); 
    cout << "2) Subtraction"; 
    el(); 
    cout << "3) Multiplication"; 
    el(); 
    cout << "4) Division"; 
    el(); 
    el(); 
    while (!(cin >> Input)) { // failed to extract 
     if (cin.eof()) { // testing eof() *after* failure detected 
     throw std::runtime_error("unexpected EOF on stdin"); 
     } 
     cin.clear(); // clear stream state 
     cin.ignore(INT_MAX, '\n'); // ignore rest of line 
     cout << "Input error. Try again!\n"; 
    } 
    } while (Input != 1 && Input != 2 && Input!=3 && Input!=4); 
    return Input; 
} 

그 추출을 선택하지 않으면

성공 실패 상태에 남아 CIN 다음, (cin.fail()) . 일단 실패한 상태에있게되면, 이후의 추출은 스트림에서 읽기를 시도하는 대신 즉시 반환되어 효과적으로 아무런 작업도 수행하지 않고 무한 루프로 이어집니다.

+0

+1 기본 문제를 해결합니다. 아직도 힐랄이 쓴대로, 아마도 그가 관심있는 숯이다 –

+0

@ 대니얼 퍼슨 : 나는 [의심] (http://stackoverflow.com/questions/4865561/how-do-i-prevent-a-runaway-input- 사용자가 입력 한 루프 요청시/4865643 # comment-5407805). –

관련 문제