私は試した
sscanf(str, "%016llX", &int64 );
しかし、安全ではないようです。型キャストを行うための高速で安全な方法はありますか?
ありがとう〜
私は試した
sscanf(str, "%016llX", &int64 );
しかし、安全ではないようです。型キャストを行うための高速で安全な方法はありますか?
ありがとう〜
scanf
家族の機能を気にしないでください。それらを堅牢に使用することはほとんど不可能です。の一般的な安全な使用法は次のstrtoull
とおりです。
char *str, *end;
unsigned long long result;
errno = 0;
result = strtoull(str, &end, 16);
if (result == 0 && end == str) {
/* str was not a number */
} else if (result == ULLONG_MAX && errno) {
/* the value of str does not fit in unsigned long long */
} else if (*end) {
/* str began with a number but has junk left over at the end */
}
は、文字列のオプションのプレフィックス、およびオプションの最初の空白と記号文字 (または) をstrtoull
受け入れることに注意してください。これらを拒否したい場合は、 を呼び出す前にテストを実行する必要があります。たとえば、次のようになります。0x
+
-
strtoull
if (!isxdigit(str[0]) || (str[1] && !isxdigit(str[1])))
過度に長い数値表現 (先行ゼロ) も禁止したい場合は、 を呼び出す前に次の条件を確認できますstrtoull
。
if (str[0]=='0' && str[1])
もう 1 つ注意すべき点は、「負の数」は変換の範囲外と見なされないことです。代わりに、プレフィックスの-
は、符号なし値に適用される C の単項否定演算子と同じように扱われるため、たとえば(を設定せずに)strtoull("-2", 0, 16)
を返します。ULLONG_MAX-1
errno
あなたのタイトル(現在)は、あなたが提供したコードと矛盾しています。タイトルが元々あったこと(文字列を整数に変換する)を行いたい場合は、この回答を使用できます。
関数を使用できます。これは、数値のテキスト表現を読み取ることに特化した関数とはstrtoull
異なります。sscanf
const char *test = "123456789abcdef0";
errno = 0;
unsigned long long result = strtoull(test, NULL, 16);
if (errno == EINVAL)
{
// not a valid number
}
else if (errno == ERANGE)
{
// does not fit in an unsigned long long
}
私がこの回答を書いた時点で、あなたのタイトルは uint64_t を文字列に書き込むことを示唆していましたが、コードは反対のことを行いました (16 進文字列を uint64_t に読み込んでいます)。私は「両方の方法」と答えました:
<inttypes.h>
ヘッダーには、..._t
型を安全に処理するための変換マクロがあります。
#include <stdio.h>
#include <inttypes.h>
sprintf( str, "%016" PRIx64, uint64 );
または(それが実際にあなたがやろうとしていることである場合)、その逆:
#include <stdio.h>
#include <inttypes.h>
sscanf( str, "%" SCNx64, &uint64 );
scanf()
関数ファミリでは幅などを強制できないことに注意してください。取得したものを解析しますが、入力が期待されるフォーマットに従っていない場合、望ましくない結果が生じる可能性があります。ああ、scanf()
関数ファミリは (大文字の) "X" ではなく (小文字の) "x" しか認識しません。