web-dev-qa-db-ja.com

符号なし整数のatoiと同等

私はatoiを含む2つの操作をしていますが、atoiはこれらを符号付き整数に変換してラップアラウンド整数オーバーフローを引き起こすため、符号なし整数でこれを行う方法を疑問に思っています。 32ビットの符号なし整数を使用したいのですが、atoiは事実上31ビットの符号なし整数に制限しています。

 if (multiplication_is_safe(atoi(argv[1]),atoi(argv[3])))
    {
     printf("%s * %s = %u \n", argv[1], argv[3], atoi(argv[1]) * atoi(argv[3]));
      return 0;
    }  else
16
John

簡単な答えは、代わりに strtoul() を使用することです。

長い答えは、必要なものがすべて32ビットの符号付き整数であるか、符号なしの31ビットに満足している場合でも、atoi()関数は、あなたがしているようには見えないことです。

既に述べたように、 atoi() 関数は文字列を整数に変換します。通常の符号付き整数。ただし、atoi()does n'tがしないのはエラー処理です。 atoi()の仕様では、「値を表現できない場合、動作は未定義です。

Strto *()ファミリの関数はすべてエラーの処理方法を明確に指定するため、すべての場合でatoi()strtol()(文字列をlongに変換)の呼び出しに置き換える必要があります。符号なし整数を処理したいので、strtoul()(文字列を符号なしlongに変換)を使用する必要があります。

また、より大きな数値を処理する場合は、文字列をlong longまたはunsigned long longに変換するstrtoll()およびstrtoull()関数があることに注意してください。 (そして、その間のすべてを気にせずに可能な限り最大の整数値を処理したい場合は、タイプ_intmax_t_の値を返すstrtoimax()strtoumax()があります_uintmax_t_それぞれ。)

POSIXドキュメント:

プラットフォームによっては、 strtoul がおそらく必要です。

Strtoul()関数は、nptrの文字列の最初の部分を、指定された基数に従って符号なしlong int値に変換します。これは2から36の間、または特別な値0でなければなりません。

2