2017-02-01 9 views
0

ここに私の教科書の簡単な問題があります。その中で、非数値入力を最初に検出するために入力ストリームを使用しようとしています。そして、それが '|'で始まっているかどうかを確認します。プログラムを終了させる文字:何か間違った入力ストリームをC++で入力した場合

int main() 
{ 
    double n1, n2; 
    char Finisher; 
    while (true) { 
     std::cout << "Enter number 1:\n"; 
     if (std::cin >> n1) {} 
     else { 
      std::cin >> Finisher; 
      if (Finisher == '|') break; //Condition that must lead to program termination. 
      std::cin.clear(); 
      std::cin.ignore(40000,'\n'); //40000: only a big number 
     } 
     std::cout << "Enter number 2:\n"; 
     if (std::cin >> n2) {} 
     else { 
      std::cin >> Finisher; 
      if (Finisher == '|') break; 
      std::cin.clear(); 
      std::cin.ignore(40000, '\n'); 
     } 

     if (n1 < n2) { 
      std::cout << "The smaller value is: " << n1 << " \nThe larger value is: " << n2 << '\n'; 
      if ((n1 - n2) < 1.0/100 && (n1 - n2) > -1.0/100) { 
       std::cout << "The values are almost equal\n"; 
      } 
     } 
     else if(n1>n2){ 
      std::cout << "The smaller value is: " << n2 << " \nThe larger value is: " << n1 << '\n'; 
      if ((n1 - n2) < 1.0/100 && (n1 - n2) > -1.0/100) { 
       std::cout << "The values are almost equal\n"; 
      } 
     } 
     else { std::cout << "both values are equal\n"; } 
    } 
    return 0; 
} 

問題は、私の「フィニッシャー」char型の変数は無用のようだ、と任意の非数値入力(種類の)が失われるということです!私が入力したものに関係なく、別の固定文字が入力されます。私の場合は、常にこれのようになります:enter image description here 何が問題なのですか? ありがとうございます。クリア()までの移動

+0

ちょうどニッピックです。あなたはさらに* "DRY - あなた自身を繰り返さない" *をしたいかもしれません。 – WhiZTiM

+0

文字列(または[行全体](http://en.cppreference.com/w/cpp/string/basic_string/getline))を読み込まないようにするには、最初の文字[数字である](http: //en.cppreference.com/w/cpp/string/byte/isdigit)し、[文字列を整数に変換する](http://en.cppreference.com/w/cpp/string/basic_string/stol )。数字でなければ '' | ''をチェックし、見つからなければ入力を破棄します。 –

+0

@Yuriy lvaskevych std :: cinの失敗した状態を変更して新しい入力を受け入れることができるようにし、無視して以前の入力を削除します。 (彼らの名前(明確で無視されている)は、彼らがやっていることと少し異なります) –

答えて

1

が動作しているようです:

if (std::cin >> n1) {} 
    else { 
     std::cin.clear(); 
     std::cin >> Finisher; 
     if (Finisher == '|') break; //Condition that must lead to program termination. 
     std::cin.ignore(40000,'\n'); //40000: only a big number 
    } 
0

問題は読み取りが失敗したら、あなたclearまで何かを読み取ることができない場所、cinた状態であるということであること。 Finisherで読む前にcin.clear();に電話する必要があります。

もちろん、あなたはFinisherの別の文字で読んでいる位置にあなたを置きます。単一のトークンを読み込み、それが数字かパイプ文字かをチェックするほうがよりエレガントです。

#include <cstdlib> 
#include <iostream> 
#include <sstream> 
#include <stdexcept> 
#include <string> 

typedef double number; 

number parse_number() { 

    static std::string in; 
    static std::istringstream stream; 
    number ret; 

    std::cin >> in; 
    stream.clear(); 
    stream.str(in); 

    if (stream >> ret) 
     return ret; 

    if (in.front() == '|') 
     std::exit(0); 

    std::ostringstream error; 
    error << "Could not parse token, \"" << in << ".\""; 
    throw std::runtime_error(error); 

} 

int main() { 

    while (true) { 

     const number n1 = parse_number(); 
     const number n2 = parse_number(); 

     // Do stuff with the numbers. 

    } 

} 
関連する問題