2015-12-05 6 views
0

У меня есть следующий код C:Почему sscanf% lx читает «0» для любого первого uint32_t в 64-битной среде?

uint32_t a = 1, b = 2; 
sscanf("0xbadf00d 0xdeadbeef", "%lx %lx", &a, &b); 
printf("%lx %lx", a, b); 

На 64-битной Linux машины с помощью GCC, если я компилирую с флагом -m32 я получаю правильный выход: badf00d deadbeef, но по умолчанию я получаю странный вывод 0 deadbeef ,

Что происходит во втором случае? Я использую неправильный символ спецификатора преобразования или, есть ли способ исправить проблему без этого флага компилятора?

+1

Are вы использовали для программирования в Windows? В Windows 'long' - 32 бита. Почти везде «длинный» имеет ту же ширину, что и указатель, поэтому 32 бита в 32-битных системах и 64 бита в 64-битных системах. –

+0

Да; что было источником моей путаницы – Dorj

+0

Я запускаю ubuntu linux 14.04 на amd64 cpu. Без параметра '-m32' компилятор вызывает несколько предупреждений. После исправления всех этих предупреждений код компилируется без проблем и выводит правильные значения. При компиляции всегда включайте все предупреждения, затем устанавливайте эти предупреждения. (для gcc, при минимальном использовании: '-Wall -Wextra -pedantic') – user3629249

ответ

1

Вы используете модификатор l длину, которая для unsigned long, но uint32_t является не беззнаковой долго на 64-битных системах, с единственным исключением Windows. Не существует стандартного модификатора длины для uint32_t, но в заголовке есть макросы, которые содержат модификатор длины (обычно это пустая строка).

Портативное решения использовать макросы, определенные в <inttypes.h>:

#include <stdint.h> 
#include <stdio.h> 
#include <inttypes.h> 

int main() { 
    uint32_t a = 1, b = 2; 
    sscanf("0xbadf00d 0xdeadbeef", "%" SCNx32 " %" SCNx32, &a, &b); 
    printf("%" PRIx32 " %" PRIx32, a, b); 
} 

На почти любой системе, вы на самом деле использовать, это то же самое, как в следующем, после макроподстановок:

#include <stdint.h> 
#include <stdio.h> 

int main() { 
    uint32_t a = 1, b = 2; 
    sscanf("0xbadf00d 0xdeadbeef", "%x %x", &a, &b); 
    printf("%x %x", a, b); 
}