2011-10-17 6 views
0

입력을 쉽게 추출하고 올바른 유형의 유효성을 검사하려면 다음을 사용합니다. 그러나 파일 EOF의 끝은 해고되지 않습니다.C++ 템플릿 입력 유효성 확인

template< typename T > 
std::istream& read(std::istream &istr, T &val) 
{ 
    std::string s; 
    std::getline(istr, s); 

    if (istr.good()) 
    { 
     s.erase(s.find_last_not_of(" \n") + 1); 

     std::stringstream iss(s); 

     iss >> val; 

     if (! iss.good()) 
      istr.setstate(std::ios::failbit); 

     char c; 
     if (iss.get(c)) 
      istr.setstate(std::ios::failbit); 
    } 

    return istr; 
} 
int main(int argc, char **argv) 
{ 
    int input = 0; 

    std::cout << "Please enter an integer>" << std::flush; 

    for (;;) 
    { 
     if (read(std::cin, input)) 
      break; 

     std::cin.clear(); 
     std::cout << "Please, enter only an INTEGER>" << std::flush; 
    } 

    std::cout << "Press <enter> to quit>"; 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    return 0; 
} 

입력 한 "111"은 정수로 유효성 검사를하지 않습니다.

+0

이것은 단일 문자 가져 오기에도 실패합니다. – rem45acp

답변

1

iss >> val은 모든 문자를 읽고 스트림의 끝을 "감동"하므로 매회 EOF를 설정합니다.

template< typename T > 
std::istream& read(std::istream &istr, T &val) 
{ 
    std::string s; 
    std::getline(istr, s); 

    if (istr.good()) { 
     std::istringstream iss(s); //leave the '\n' 

     if (! (iss >> val)) 
      istr.setstate(std::ios::failbit); 

     //if it gets another character that isn't a newline 
     char a=0; 
     if (iss.get(a) && a!='\n') 
      istr.setstate(std::ios::failbit); 
    } 

    return istr; 
} 
+0

입력 유형을 int로 변경하고 "1"(공백을 알아 차림)을 입력하면 받아 들여서는 안됩니다. – rem45acp

+0

@ rem45acp : 공백을 _ 중요하게하려면 표준 I/O 스트림이 작업에 적합한 도구가 아닙니다. [Boost.Spirit] (http://www.boost.org/libs/spirit/)의'auto_' 파서를 쏜다. – ildjarn

+0

모든 형식화 된 입력은 공백을 건너 뜁니다. 공백을 허용하지 않으려면 형식화되지 않은 입력을 사용하여 사용자 고유의 루틴을 작성해야합니다. –