2

32ビットマシンで16進数から整数への変換を行おうとしています。これが私がテストしているコードです、

int main(int argc,char **argv)
{
    char *hexstring = "0xffff1234";
    long int n;

    fprintf(stdout, "Conversion results of string: %s\n", hexstring);
    n = strtol(hexstring, (char**)0, 0); /* same as base = 16 */
    fprintf(stdout, "strtol = %ld\n", n);
    n = sscanf(hexstring, "%x", &n);
    fprintf(stdout, "sscanf = %ld\n", n);
    n = atol(hexstring);
    fprintf(stdout, "atol = %ld\n", n);
    fgetc(stdin);

    return 0;
  }

これは私が得るものです:

 strtol = 2147483647 /* = 0x7fffffff -> overflow!! */
 sscanf = 1 /* nevermind */
 atol = 0   /* nevermind */

ご覧のとおり、strtolを使用すると、オーバーフローが発生します(errnoでも確認しました)が、0xffff1234は有効な整数の32ビット値であるため、何も起こらないと思います。私は4294906420または-60876のいずれかを期待します

私は何が欠けていますか?

4

2 に答える 2

6

オーバーフロー効果が必要ない場合は、関数の符号付きバリアントを使用しないでください。strtoul()代わりに使用してください。

次のコードで:

#include <stdio.h>
int main(int argc,char **argv) {
    char *hexstring = "0xffff1234";
    long sn;
    unsigned long un;

    fprintf(stdout, "Conversion results of string: %s\n", hexstring);

    sn = strtoul(hexstring, (char**)0, 0);
    fprintf(stdout, "strtoul   signed = %ld\n", sn);

    un = strtoul(hexstring, (char**)0, 0);
    fprintf(stdout, "strtoul unsigned = %lu\n", un);

    return 0;
}

私は得る:

Conversion results of string: 0xffff1234
strtoul   signed = -60876
strtoul unsigned = 4294906420

strtol()動作はこれらの関数内にあるため、呼び出し時にこれを制御することはできません。標準には次のように書かれています。

strtol、strtoll、strtoul、およびstrtoull関数は、変換された値を返します(存在する場合)。変換を実行できなかった場合は、ゼロが返されます。正しい値が表現可能な値の範囲外の場合、LONG_MIN、LONG_MAX、LLONG_MIN、LLONG_MAX、ULONG_MAX、またはULLONG_MAXが返され(戻りタイプと値の符号(存在する場合)に応じて)、マクロERANGEの値は次のようになります。 errnoに保存されます。

于 2012-07-24T09:47:13.400 に答える
3

の最小範囲は -2147483647 から2147483647 です。実装上longの の範囲は、-2147483648 から 2147483647 である可能性があります。long

の定義にstrtol()よると、変換された値が の範囲外の場合longLONG_MINまたはLONG_MAXが変換された値の符号に従って返され、 にERANGE格納されerrnoます。この場合、変換された値0xffff1234は範囲外です - より大きいのでLONG_MAXLONG_MAXが返されます。

ところで、あなたの への呼び出しは の変換された値を の戻り値でsscanf()上書きしています。これは 1 で、変換が 1 回成功したことを示します。nsscanf()

于 2012-07-24T10:08:06.003 に答える