1

すでに機能しているコードをクリーンアップしたいと考えています。まず第一に、これは代入のためのものであり、代入は int を int として、double を double として取る必要があることを指定していますif(number%1==0)

入力を処理するだけにコードを切り詰めました (正しく動作していることを確認するための出力ステートメントを使用)。

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() == '.')より良いオプションですが、私がここで達成しようとしていることを達成するための最良の方法は何かに興味があります. 何か案は?

そして、これを「宿題だ」とだけ断らないでください。強調したいのは、私のプログラムは、宿題の余分なクレジットの部分でさえ求められる以上のことをすでに行っているということです. 私は言語についてもっと学び、この種の入力を処理するための最良の方法は何かを学ぼうとしています.

4

3 に答える 3

2

のようなもの"1.0"も double と見なす必要があると思います。これにより、double を読み取り、それが実際に整数であるかどうかを確認するなどの作業がほとんどなくなります。

唯一の方法は、データを解析して、 として解釈できるものに遭遇するかどうかを確認することですint。ストリームの変換関数を使用する場合、これは入力を 2 回スキャンすることを意味します。明らかな解決策は、入力を文字列に入れることです。これらは、複数回スキャンする方がはるかに簡単です。許可されていない場合は、 を使用istream::tellgして位置を記憶し、先にスキャンし、決定しistream::seekgたら元の場所に戻ることができます。しかし、あなたのインストラクターがどのような規則を課したかはわかりません。

シークできない場合は、手でハッキングしてみてください。最初に を読み取りint、次に次の文字をのぞき見します。それが の場合'.'、double を読み取ることができます。これにより、小数部分が得られ、既に読み取った整数に追加できます。'E'or と andの場合'e'は、少し難しくなります。おそらく、先に進み、int を読み取り、pow手動で使用する必要があります。しかし、これは完璧とは言えません。 double の形式が の場合 "1.2E6"、「小数」部分として 200000 になります。これを検出し、既に読み取った整数をスケーリングする手段が必要になります。数値が".3"の場合、整数を読み取るときにエラーが発生します。事前にこれを確認することもできます (ただし、忘れないでください)。"-.3")、または他の操作を行う前にエラーをリセットしてください。そしてもちろん、double の整数部分がint(または a でさえlong long) に収まらない可能性があります。

全体として、私には少し人工的なようです。実際には、文字列を読み取り、それに対して正規表現を照合して、それをどのように解釈するかを決定します。

于 2013-09-25T16:54:10.680 に答える
1

最初に行全体を文字列として読み取り、小数点を確認してから、その行を stringstream に送り、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;
}
于 2013-09-25T16:14:13.803 に答える
0

あなたの仕様を考えると、私は a を読み、std::stringそれが整数以外のものであるかどうかを確認し、結果に応じて asintまたは as として解析しdoubleます。例えば

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";
        }
}
于 2013-09-25T16:15:58.503 に答える