0

私は次の簡単なコードを持っています:

#include <iostream>
int main()
{
   int a;
   std::cout << "enter integer a" << std::endl;
   std::cin >> a ;

   if (std::cin.fail())
   {
      std::cin.clear();
      std::cout << "input is not integer, re-enter please" <<std::endl;
      std::cin >>a;
      std::cout << "a inside if is: " << a <<std::endl;
   }
   std::cout << "a is " << a <<std::endl;
   std::cin.get();
   return 0;
}

上記のコードを実行して次のように入力すると、次のよう1.5に出力されますa is 1。参考:gcc4.5.3でコードをコンパイルして実行します。

これはcin、整数を期待しているのにfloatが表示された場合、暗黙的に変換を行うことを意味します。それでcin、これは、浮動小数点数を見るとき、それがfail()状態にないことを意味しますか?なぜそうなのですか?C ++が>>演算子で暗黙の変換を行うためですか?

また、次のコードを試して、この投稿のアイデアに従って、指定された入力番号が整数であるかどうかを判断しました。指定された数値が整数であるかどうかをテストします。

#include <iostream>
bool integer(float k)
{
    if( k == (int) k) return true;
    return false;
}

int main()
{
   int a;
   std::cout << "enter integer a"<< std::endl;
   std::cin >> a ;

   if (!integer(a))
   {
     std::cout << "input is not integer, re-enter please" ;
     std::cin.clear();
     std::cin >> a;
     std::cout << "a inside if is: " << a <<std::endl;
   }
   std::cout << "a is " << a <<std::endl;
   std::cin.get();
   return 0;
}

このコードブロックは、float入力で実行するとブロックをaスキップするだけなので、整数かどうかをテストすることもできませんでした。if

では、なぜこれがcinでユーザー入力を取得する場合に当てはまるのでしょうか。たまに入力を入れたいのに、誤って189入力した場合、この場合は悪い結果になります。それで、これはユーザー入力整数を取得するために使用することは良い考えではないことを意味しますか?18.918cin

ありがとうございました。

4

3 に答える 3

6

整数を読み取り、それに1.5の入力を与えると、整数1が表示され、それは整数の一部ではないため、ピリオドで停止します。「.5」はまだ入力にあります。これが整数部分のみを取得する理由であり、2回目の入力を待機していないように見える理由でもあります。

これを回避するには、整数の代わりにfloatを読み取って値全体を読み取るか、整数を読み取った後に行に他に何かが残っているかどうかを確認します。

于 2013-03-24T04:01:53.747 に答える
1

operator>>ユーザー入力を読み取るとき、ユーザー入力は通常行ベースであり、エラーが発生しやすいため、使用しないことを好みます。一度に1行ずつ読んで、検証するのが最善だと思います。

 std::string   line;
 std::getline(std::cin, line);

これにより、さまざまな種類の番号を簡単に確認できます。

 std::stirngstream linestream(line);
 int  val;
 char c;

 if ((linestream >> val) && !(linestream >> c))
 {
     // Get in here if an integer was read.
     // And there is no following (non white space) characters.
     // i.e. If the user only types in an integer.
     // 
     // If the user typed any other character after the integer (like .5)
     // then this will fail.
}

もちろん、ブーストはすでにこれをサポートしています:

val = boost::lexical_cast<int>(linestream); // Will throw if linestream does 
                                            // not contain an integer or
                                            // contains anything in addition
                                            // to the integer.

もちろん、ブーストはフロートも変換します。

于 2013-03-24T06:09:23.083 に答える
1

コーディングが不十分なスニペットがありますが、機能します。この方法は非常に単純ですが、入力値が無効な場合は処理されません。詳細:https ://en.cppreference.com/w/cpp/string/byte/atof

static float InputFloat(std::string label)
{
    std::string input;
    std::cout << label;
    std::cin >> input;
    return atof(input.c_str());
}

int main()
{
    float value = InputFloat("Enter some float value: ");
    std::cout << "value = " << value;
    return 0;
}
于 2020-02-29T05:35:11.617 に答える