c++ - これは、浮動小数点値を使用して入力検証を行う正​​しい方法ですか?

原文 c++ validation input floating-point

入力検証の調査にかなりの時間を費やした後、私はいくつかのアイデアを組み合わせてこれを思いつきました:

文字列が有効なdoubleかどうかをチェックする関数...

bool isDouble(double& destination, string& source)
{ // 64 bit
  bool goodValue = false;

  if (!source.empty()) {
    errno = 0;
    char *garbage = nullptr;
    destination = strtod(source.c_str(), &garbage);

    if (*garbage == '\0' && errno != ERANGE)
      goodValue = true;
  }

  return goodValue;
}


文字列に有効な32ビットintegerがあるかどうかをチェックする関数...

bool isLong(long& destination, string& source)
{ // 32 bit (base 10)
  const short BASE = 10;
  bool goodValue = false;

  if (!source.empty()) {
    errno = 0;
    char* garbage = nullptr;
    destination = strtol(source.c_str(), &garbage, BASE);

    if (*garbage == '\0' && errno != ERANGE)
      goodValue = true;
  }

  return goodValue;
}


実装例

using namespace std;

int main() {
  string buffer;
  double value;

  cout << "Enter a value: ";
  getline(cin, buffer, '\n');

  if (isDouble(value, buffer))
    cout << "Value: " << value << endl;
  else
    cout << "ERROR: Invalid input\n";

  return 0;
}


このアプローチで何かを見落としている場合、誰かがコメントできますか?
答え
「正しい」方法はわかりませんが、私がどのように行うかは確かではありません。まず、おそらく最も明白なのは、このコードのチャンクです。

    for (i = 0, d = 0; i < BUFFSIZE && buffer[i] != 0 && buffer[i] >= '0' &&
             buffer[i] <= '9' || (buffer[i] == '.' && d == 0); i++)
            if (buffer[i] == '.') ++d;


いくつかの場所で重複しています(少なくとも、他のインスタンスは同じだと思います。とにかく多分同じです)。

次に、通常は浮動小数点として受け入れられる1e23-1.2などの数値を許可していないように見えます。

オフハンドで、私は入力を変換するためにstrtodを使用すると思います。 2番目のパラメーターを使用して、変換が入力文字列の終わりに達したかどうかを検出できます(達していない場合は、入力の少なくとも一部が受け入れられなかったことがわかります)。次に、(明らかに)戻り値が目的の範囲内にあったことを確認します。
関連記事

c++ - コンパイル後のC++コンストラクタの本当のシグネチャは何ですか

c++ - Valgrind-初期化されていない値とバイト?

c++ - C++ constオーバーロードとコード共有

c++ - OpenGL 2.1でのglDrawRangeElementsの使用

c++ - POSIX読み取りの一時停止をマイクロ秒の範囲で認識する

c++ - Qtで、モデルからリストビューのアイテムの背景色をリセットするにはどうすればよいですか?

c++ - 実装ファイルでコンストラクタを使用するにはどうすればよいですか?

c++ - cursesライブラリーの使用時にmove()またはwmove()を使用するとカーソルが移動しない

c++ - プログラムでシステム情報を開く

c++ - Boost::Spiritを使用してエスケープされた文字列を解析する