次のプログラムを C++ で作成しました。
このプログラムの問題は、ユーザーが負の数を入力した場合、それが行に引っかからないことですif(!cin)
。符号なし整数は負の数を受け入れることができないと思いました。次に、サイズに負の数を入力すると、それがキャッチされif(!cin)
ず、プログラムがエラーメッセージなしで実行を継続するのはなぜですか?
を利用できませんif(size < 0)
。符号なし整数が負の入力の問題をどのように解決できるかを示したいと思います。
ほとんどのプラットフォームでの符号なし整数と符号付き整数の違いは符号ビットです...それ以外は、実際のバイナリ値は同じです。バイナリ値が表す型の符号性に応じて、2 つの異なる方法で解釈されるだけです。 . したがって、負の値の入力を符号なしの値として確実に「表す」ことができます...その値として再解釈されることはありませんが、ストリームにエラーが設定されることなく、その値として確実に入力できます。
C ++の第一人者でも何でもありませんが、cin.fail()
代わりに !cin を使用して、cin.clear()
より深い説明でバッファをクリアしてみましたか
または、より大きな符号付き整数型を使用することもできます。
long long n = -1;
cout << "Enter a number: ";
cin >> n;
if( !cin.good() )
cout << "Not a valid number." << endl;
else if( n > UINT_MAX )
cout << "Overflow, value is more than UINT_MAX." << endl;
else if( n < 0 )
cout << "Negative, value is less than 0." << endl;
else {
unsigned int m = (unsigned int)n;
cout << "Valid unsigned int was input: " << m << "." << endl;
}
ユーザーが負の数を入力できないようにする場合は、入力を符号付きの数値として受け取り、それがゼロ以上であることを確認します。
標準では、基本的に、型の範囲外の整数型に数値を割り当てようとすると、値が範囲内になるまで型の大きさの倍数が加算または減算されると規定されています。
たまたま、値が 2 の補数として表現され、signed および unsigned int の範囲内にある場合、これはまったく同じビット パターンが任意の値に割り当てられることを意味します。負の値はすべて 1 のビット パターンを持ち、unsigned int の可能な最大値に変換され、元の値に unsigned int の大きさを加えたものと同等です。-1 + 232
C および C++ では、符号なし型のオブジェクトに負の値を割り当てることができます。結果は、 modulo2^n
で縮小された元の値です。ここn
で、 は符号なし型のサイズです。したがって、たとえば、 にunsigned i = -1;
初期化i
されUINT_MAX
ます。
チェック は、ファイルの終わりなど、何も読み取られなかったif(!cin)
ことのみを示します。
整数は、入力が正になることを強制unsigned
しません。これは、値が常に正として解釈されることを意味するだけであり ( sign bitを参照)、数値が実際に負の場合に劇的な影響を与える可能性があります。
おそらく最善の策は、符号付き整数を入力し、それが正かどうかをコードでテストすることです。