2012-04-24 4 views
4

나는 사용자가 답변에 있어야하는 데이터의 정확한 유형을 할당 한 경우 확인하는 템플릿 함수를 쓰고 있어요에 IStream을 입력에 성공 예를 들면 다음과 같습니다.부동 소수점 데이터가 예기치 않게 정수

int main(){ 

    int E; 
    cout<<"Enter an integer: "<<endl; 
    E = clear_and_read<int>(cin); 
    cout<<E<<endl; 

} 
같은 기능 clear_and_read가 정의

: 내가 대신 integerstring를 입력하려고하면

template <class T> T clear_and_read(istream& inputstream){ 
    cin.sync();//removes anything still in cin stream 
    cin.clear(); 
    T input; 
    inputstream>>input;  
    while(inputstream.fail()){ 
     cout<<endl<<"Please ensure you are inputting correct data type. Suggested data type: "<< typeid(input).name() <<"."<<endl; 
     cin.sync(); 
     cin.clear(); 
     inputstream>>input; 
    } 
    return input; 
} 

지금이 작품,하지만 난 double를 입력 할 때 그냥 첫 번째 값의 할당합니다. 예 : 5.678이 5가됩니다.

doubleint으로 읽는 중 플래그 기능을 사용하려면 어떻게해야합니까?

+0

'typeid (input)'이것은 생각할 수있는 더 많은 문제를 묻는 것입니다. – orlp

+0

나는 사용자를 돕기위한 제안으로 사용하기 때문에 너무 위험하지 않을 것이라고 생각했다. 코드 내에서 비교하지 않았다. 또한 수정 : sixlettervariables에 감사드립니다. – QuantumO

답변

3

나는 당신이 가지고있는 것보다 약간 다른 것을 시도하려고합니다. 특히, 내가 입력 스트림의 에러 상태를 수정하려고하지 않을 :

// Untested 
template <class T> T clear_and_read(istream& inputstream) { 
    std::string inputString; 
    while(1) { 
    try { 

     // Grab one maximally-sized whitespace-delimited chunk of input 
     inputstream >> inputString; 

     // Note: lexical_cast throws if there are any extraneous characters. 
     return boost::lexical_cast<T>(inputString); 

    } catch (boost::bad_cast&) { 
     std::cout << "\nPlease ensure you are inputting correct data type. Suggested data type: "<< typeid(input).name() <<".\n"; 
    } 
    } 
} 


: 당신이 당신의 컴파일 환경에서 사용할 수 부스트가없는 경우, lexical_cast 자신을 구현하기가 매우 간단하다. 막히면 도움을 청하십시오.


참고 : 여기에


편집 부스트에 의존하지 않는 완벽하게 테스트 버전입니다.

#include <exception> 
#include <sstream> 
#include <string> 
#include <iostream> 
#include <typeinfo> 

template <class T> T clear_and_read(std::istream& inputstream) { 
    std::string inputString; 
    while(inputstream) { 
     // Grab one maximally-sized whitespace-delimited chunk of input 
     inputstream >> inputString; 
     std::istringstream itemstream(inputString); 

     // Convert it: 
     T t; 
     itemstream >> t; 

     // See if conversion worked and consumed everything 
     if(itemstream && (itemstream.get() == EOF)) { 
     // SUCCESS 
     return t; 
     } 

     // oops 
     std::cout << "\nPlease ensure you are inputting correct data type. Suggested data type: "<< typeid(T).name() <<".\n"; 
    } 
    std::cout << "What to do with EOF?\n"; 
    return T(); 
} 

int main() { 
    clear_and_read<int>(std::cin); 
    clear_and_read<double>(std::cin); 
} 
+0

외부 라이브러리를 향상시키고 있습니까? - 불행하게도 나는 쓰고있는 코드 조각을 표준 C++로 고수해야한다. – QuantumO

+0

괜찮습니다.'boost :: lexical_cast'는 표준 C++에서 자신을 구현하는 것이 간단합니다. 그렇게 할 필요가 있는지 물어보십시오. –

+0

와우. 화려한 대답! 고맙습니다. 공백 문자열 (예 : "John Smith")을 허용하도록이 코드를 변경할 수 있습니까? 아마도 – QuantumO

1

입력 스트림의 전체 입력이 소비되었는지 확인해야합니다. 연산자 >>는 첫 번째 비 숫자를 만날 때마다 정수로의 변환을 중지합니다. 마찬가지로 "3.14qwe"은 3.14 double로 변환됩니다.

관련 문제