2012-07-24 10 views
2

32 비트 컴퓨터에서 16 진수에서 정수로 변환하려고합니다.16 진수 문자열을 long으로 변환하십시오.

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

보시다시피, 나는 (나는 또한 errno를 확인) 오버 플로우를 얻을 strtol 함수와 함께, 비록 내가 것 : 여기에 테스트입니다 코드는, 내가 무엇을 얻을

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; 
    } 

가된다 0xffff1234가 유효한 정수 32 비트 값이므로 아무 것도 일어나지 않을 것으로 예상하십시오. 나는 어느 쪽이든 예상 할 것이다 4294906420 또는 그 밖의 -60876

나는 무엇을 놓치고 있습니까?

+0

기본 숫자를 0으로 설정하는 것이 확실한가요? 16 * strtol (hexstring, (char **) 0, 0) * strtol (hexstring, (char **) 0, * * 16 **) * –

+0

@AG 밑수를 0으로 설정하면 'strtol'은 기본 16, 10 또는 8을 사용할지를 입력 문자열의 시작 부분에서 알아 내기 시작합니다. –

+0

오른쪽, 잊어 버렸습니다! 감사 ! –

답변

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; 
} 

내가 얻을 : 행동이 내에서 이러한 기능 때문에 strtol()를 호출하고 그 형제들 때

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

당신이 제어 할 수 없습니다. 표준은 다음과 같이 말합니다 :

strtol, strtoll, strtoul 및 strtoull 함수는 변환 된 값이있는 경우이를 반환합니다. 변환을 수행 할 수 없으면 0이 리턴됩니다. 올바른 값이 표현할 수있는 값의 범위를 벗어나면 LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX 또는 ULLONG_MAX가 리턴되며 (값의 반환 유형과 부호에 따라), ERANGE 매크로의 값은 errno에 저장됩니다.

+0

그게 올바른 해결책입니다. Meh, 나는 문서 앞에서 나 앞에서 그것을 보았지만 그것을 보지 못했다 : D +1. :) – ATaylor

+0

@juampa 함수 안에서 오버플로가 발생합니다. 왜 두 가지 기능이 있을까요? 그러나 당신이 서명 한대로 'n'의 내용을 출력한다면 -60876을 얻을 것입니다 ... meh, 그의 편집은 저를 이깁니다 : D – ATaylor

3

long의 최소 범위는 구현에 long의 범위는 -2147483648 strtol()의 정의는 말한다

2147483647 가능성이 2147483647 -2147483647입니다 변환 된 값의 범위를 벗어나면 변환 값의 부호에 따라 long, LONG_MIN 또는 LONG_MAX이 반송되고, ERANGEerrno에 저장됩니다. 이 경우 변환 된 값 0xffff1234이 범위를 벗어났습니다. LONG_MAX보다 크므로 LONG_MAX이 반환됩니다.

그런데 sscanf()을 호출하면 의 변환 된 값이 sscanf()의 반환 값으로 덮어 쓰여지고 1은 성공적인 변환이 1되었음을 나타냅니다.

관련 문제