2013-09-25 2 views
1

나는 이미 가지고있는 코드 중 일부를 정리하려고합니다. 우선 이것은 할당을위한 것이며 할당은 int가 int로 취해지고 double이 double 등으로 지정되어야한다고 지정합니다. 그렇지 않으면 입력을 double로 가져 와서 int로 캐스팅합니다 if(number%1==0).C++ int 또는 double 입력

필자는 입력을 처리하기 위해 코드를 잘라내어 출력 문을 사용하여 제대로 작동하는지 확인했습니다.

int wholePart=0; 
double decimalPart=0; 
cout << "Input a number: "; 
cin >> wholePart; 
if(cin.peek() != '\n') 
    cin >> decimalPart; 

cout << "wholePart = " << wholePart << endl << "decimalPart = " << decimalPart << endl; 

지금 ...이 그대로 작동하고, 나는 decimalPart가 0이 아닌 경우 정수와 소수를 통합 처리하는 코드를 추가 한 후, 나는 이미 할당 요구보다 더 많은 일을했습니다, 그러나 나는 배울 것을 찾고 있는데 가능한 한이 코드를 정리하고 싶습니다.

사용자가 실제로 숫자가 아닌 문자를 입력하고 있는지 확인하기 위해 입력 섹션 전체를 다른 입력 유효성 검사와 함께 래핑 할 수 있습니다. 하지만 여기서 가장 중요한 관심사는 if(cin.peek() != '\n')으로 충분하지 않다는 것입니다. 아마도 if(cin.peek() == '.')은 더 나은 옵션이지만, 여기서 성취하고자하는 일을 성취하는 최선의 방법은 무엇인지 궁금합니다. 어떤 아이디어?

그리고 "오 숙제"라고만하지 마십시오. 나는 나의 프로그램이 이미 숙제의 추가 신용 부분조차 요구하는 것 이상으로 나아가고 있다는 것을 강조하고 싶다. 저는 언어에 대해 더 많이 배우려고 노력하고 있습니다. 이런 종류의 입력을 처리하는 가장 좋은 방법은 무엇일지도 모릅니다.

답변

2

나는 "1.0" 같은 이중뿐만 아니라 A와주의해야한다고 가정; 같은 것을 거의 없애고 실제로 정수인지 확인합니다.

유일한 방법은 데이터를 구문 분석하여 문자가 int으로 해석 될 수 있는지 여부를 확인하는 것입니다. 만약 당신이 스트림의 변환 기능을 사용하려고한다면,이 귀여운 은 입력을 두 번 스캔한다는 것을 의미합니다. 분명한 해결책은 문자열에 입력을 넣는 것입니다; 이들은 여러 번 스캔하는 것이 훨씬 쉽습니다. 허용되지 않는 경우 istream::tellg을 사용하여 위치를 암기하고 미리 스캔 한 다음 을 결정하면 istream::seekg에서 을 (를) 시작한 곳으로 되돌아 갈 수 있습니다. 하지만 강사가 부과 한 규칙을 모르겠습니다.

찾을 수없는 경우 직접 해킹 해 볼 수 있습니다. 먼저 과 int을 읽은 다음 다음 문자를 들여다 봅니다. '.' 인 경우 은 이미 읽은 정수에 추가 할 수있는 부분 부분 인 을 제공하는 double을 읽을 수 있습니다. 이 'E' 또는 'e' 인 경우 조금 더 어려워집니다. 당신은 아마, int를 읽고 사전에 pow을 사용해야합니다. 하지만 이것은 완벽하지 않습니다. 이중 형식이 "1.2E6" 인 경우 "분수"부분으로 200000이됩니다. 이것을 감지하고 읽은 정수인 정수를 확장하는 방법이 필요합니다. 숫자가 ".3" 인 경우 정수를 읽을 때 에 오류가 발생합니다. 을 미리 확인하거나 ("-.3"을 잊지 마세요) 오류를 다시 설정하거나 다른 작업을 수행하기 전에 을 재설정 할 수 있습니다. 그리고 물론, 은 double의 필수 부분이 int (또는 심지어 a long long)에 맞지 않을 수도 있습니다.

모두 내게 조금 인위적으로 보입니다. 실제로 을 문자열로 읽어 들이고 주문에서 정규 표현식과 일치시켜 해석 방법을 결정합니다.

+0

나는 전체적으로 꽤 인공적으로 보이고 분명히 과제의 제약 조건을 벗어나는 방법이 아니라는 것에 동의한다. tellg 및 seekg 함수의 기능과이를 올바르게 사용하는 방법에 대해 자세히 설명 할 수 있습니까? – nhgrif

+0

@nhgrif 그들은'std :: istream'의 표준 멤버 함수입니다 : 첫 번째는 현재 위치를 (std :: streampos'로) 반환하고, 두 번째는 이전 호출에서'std :: streampos'를 취합니다. 'tellg'을 읽고 다음 읽기를 위해 그 위치를 정합니다. –

+0

감사합니다. 나는 아마'tell (예상) '과'seekg'를 내 임무의 여분의 신용 부분을 넘어선 방법으로 구현할 것이라고 생각한다. 왜냐하면 이것들은 미래의 유용성이 더 높을 가능성이 높기 때문에'if (cin.peek() =='). ')'방법. – nhgrif

1

문자열로 먼저 전체 행을 읽는 것이 더 쉽습니다. 소수점을 확인한 다음 문자열을 int 또는 double로 변환 할 수있는 문자열 스트림으로 전달하십시오 (소수점이)을 사용할 수 :

#include <iostream> 
#include <sstream> 
#include <string> 
#include <algorithm> 

using namespace std; 

int main() { 
    string line; 
    int anInteger; 
    double aDouble; 

    getline(cin, line); 
    stringstream ss(line); 
    if (line.find('.') == string::npos) { 
    ss >> anInteger; 
    } else { 
    ss >> aDouble; 
    } 

    return 0; 
} 
+0

문자열을 읽는 것이 나의 첫 번째 생각이었고, 내가 한 일이지만,이 특정 할당은 입력을 문자열로 처리해서는 안된다는 것을 명시 적으로 나타냅니다. 그래도 고마워. – nhgrif

0

이 사양을 감안할 때, 내가 그 정수보다 다른 뭔가 int이나 double 같은 구문 분석 결과에 따라 될 수 있다면 참조 std::string을 읽을 것입니다. 예를 들어

int   integer; 
double  number; 
std::string value; 
if (std::cin >> value) { 
    if (value.find_first_of(".Ee")) { 
     if (std::istringstream(value) >> number) { 
      std::cout << "read double=" << number << '\n'; 
     } 
     else { 
      std::cout << "failed to read double from '" << value << "'\n"; 
     } 
    } 
    else { 
     if (std::istringstream(value) >> integer) { 
      std::cout << "read integer=" << integer << '\n'; 
     } 
     else { 
      std::cout << "failed to read integer from '" << value << "'\n"; 
     } 
} 
+0

문자열을 읽는 것이 처음 생각이었고 내가 한 일일 것입니다.하지만이 특정 할당은 입력을 문자열로 처리해서는 안된다는 것을 명시합니다. 그래도 고마워. – nhgrif

관련 문제