3

doubleとして宣言された3つの変数があります。

double Delay1 = 0;
double Delay2 = 0;
double Delay3 = 0;

次に、ユーザーから値を取得します。

cout << "Please Enter Propogation Delay for Satellite #1:";  
cin >> Delay1;
...

しかし、これらの値をチェックしてnullであるかどうかを確認すると(ユーザーがEnterキーを押して数値を入力しなかった場合)、機能しません。

if(Delay1  || Delay2 || Delay3 == NULL)  
      print errror...

これは毎回実行されます。
doubleとして宣言された入力が空白であるかどうかを確認する適切な方法は何ですか?

4

8 に答える 8

11

何かのようなもの

cin >> Delay1;
if(cin) { ... }

cin先頭の空白をスキップするため、指定どおりには機能しません。ユーザーは単に Enter キーを押すことはできません。彼は最初にテキストを入力する必要があります。彼が次のように入力した場合

3a

次に、入力が まで double に読み込まれa、そこで停止します。cin何も問題が見つからずa、ストリームに残ります。多くの場合、これで十分なエラー処理だと思います。しかし、ユーザーが上記のような内容を入力したときに実際に繰り返す必要がある場合は、もう少しコードが必要です。

改行までの入力全体が数値かどうかをテストする場合は、 を使用getlineし、文字列に読み取ってから数値に変換してみてください。

string delay;
if(!getline(std::cin, delay) || !isnumber(delay)) {
  ...
}

関数はisnumber文字列ストリームを使用して文字列をテストできます

bool isnumber(string const &str) {
  std::istringstream ss(str);
  double d;

  // allow leading and trailing whitespace, but no garbage
  return (ss >> d) && (ss >> std::ws).eof();
}

operator>>先頭の空白std::wsを消費し、末尾の空白を消費します。ストリームの最後までヒットすると、シグナルが送信されeofます。このようにして、次に から読み取ろうとしたときにエラーが発生するのではなく、すぐにユーザーにエラーを知らせることができますcin

double を返す、または double のアドレスを `isnumber に渡す同様の関数を作成して、解析が成功した場合に結果を書き込むことができるようにします。


operator void*また、さまざまなエラー フラグと、それらが、operator!good()fail()とどのように関連しているかを確認することも価値がありbad()ますeof()

            flag | badbit  |  failbit  |  eofbit
function         |         |           |
-----------------+---------+-----------+--------
op void*         |    x    |     x     |
-----------------+---------+-----------+--------
op !             |    x    |     x     |
-----------------+---------+-----------+--------
good()           |    x    |     x     |    x
-----------------+---------+-----------+--------
fail()           |    x    |     x     |
-----------------+---------+-----------+--------
bad()            |    x    |           |
-----------------+---------+-----------+--------
eof()            |         |           |    x
-----------------+---------+-----------+--------

xそれぞれのビットが結果に影響する場合があります。( )operator void*に変換するときに使用され、コード実行に使用されます。boolif(cin) ...operator!!cin

于 2009-08-27T17:42:33.027 に答える
4
std::cout << "Enter doubles: ";
std::cin >> d1 >> d2 >> d3;

if(std::cin.fail())
{
    // error!
}
于 2009-08-27T17:17:10.113 に答える
3

ストリーム入力が機能したかどうかを確認する方法は、ストリームをテストすることです。

if(!std::cin) throw "Doh!";

常に左の引数を返すのでoperator>>、これも機能します。

if( std::cin >> Delay1 ) 
  good();
else
  bad();

入力が失敗しても、入力ストリームは値を変更しません。したがって、あなたの場合、彼らは以前に持っていたランダムな値を保持します。ストリームをチェックせずに入力を受け入れることは絶対にしないでください。

于 2009-08-27T17:18:56.753 に答える
3

確認する必要があるのは、doubleを読み取ろうとした後の入力ストリームの状態です。

例えば

cin >> Delay1;
if (!cin.fail()) {
  // Input was a double
} else {
  // Input was something that could not be interpreted as a double
}

これは次のようにもっと簡潔に書くことができます

if (cin >> Delay1) {
  // Input was a double
} else {
  // Input was something that could not be interpreted as a double
}

入力が失敗した場合、Delay1の値は変更されないため、以前に初期化していない場合は、任意の値になります。ただし、指摘されているように、値型ではなくポインタのみがnullになる可能性があるため、「NULL」にはなりません。

于 2009-08-27T17:21:57.827 に答える
2

ここで問題が発生していることが複数あります。

まず、解析が失敗したかどうかを確認するには、を使用しますif (cin.fail()) { /* print error */ }

2番目:Delay1 || Delay2 || Delay3doubleをブール値に変換してから、それらを論理ORします。

3番目:== NULLブール値(この場合false)をポインター値と比較しますNULL。これは常にそうなると思いますtrue

于 2009-08-27T17:19:36.597 に答える
2

if条件が間違っています。if(Delay1 || Delay2 || Delay3 == NULL)Delayがゼロに等しくないか、delay2がゼロに等しくないか、Delay3がゼロの場合にtrueになります。確かにそれはあなたが望むものではありません。また、プリミティブデータ型には0を使用する必要があります。さらに、double値を絶対値と比較することは常に危険です。値が小さなイプシロン値よりも小さいかどうかを確認します。

于 2009-08-27T17:23:09.493 に答える
1

ストリーム状態を使用するだけで、doubleを読み取れなかった場合は失敗状態になります。

if(!(std::cin >> Delay1 >> Delay2 >> Delay3)) {
    // error
}
于 2009-08-27T17:21:16.063 に答える
0

変数を文字列として読み込んでから、空白かどうかを確認してから、doubleに変換する必要があると思います(有効なdoubleかどうかを確認してください。ユーザーが「hello」と入力した可能性があります)。

于 2009-08-27T17:17:09.800 に答える