我正在尝试通过以下方式将带符号的十六进制数字转换为WORD,DWORD和QWORD:

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

int main(void) {

  printf("WORD=%d\n",  (int16_t) strtol("F123", NULL, 16));
  printf("DWORD=%d\n", (int32_t) strtol("FFFFF123", NULL, 16));
  printf("QWORD=%lld\n", (int64_t) strtol("FFFFFFFFFFFFF123", NULL, 16));

  return 0;
}


但是它返回以下内容:

WORD=-3805
DWORD=2147483647
QWORD=2147483647


http://ideone.com/mqjldk

但是,为什么DWORD和QWORD强制转换也不返回-3805呢?

我的意思是:存储在DWORD中的0xFFFFF123将包含以十进制表示的-3805值,而不是2147483647

预期产量:

WORD=-3805
DWORD=-3805
QWORD=-3805


您有按位选择吗?

最佳答案

如果long int有32位,则0xFFFFF123不在long int范围内,因此strtol()返回LONG_MAX(在我们的情况下为0x7FFFFFFF = 2147483647)。

使用strtoull()将字符串转换为至少64位的无符号整数,并在继续操作之前始终检查错误。

要打印具有指定位大小的整数,请使用以下命令:

printf("foo=%"PRIu32"\n",(uint32_t) foo);


更好的方法:

#include <stdio.h>
#include <stdlib.h>
#define __STDC_FORMAT_MACROS  //we need that for PRI[u]8/16/32 format strings
#include <inttypes.h>
#include <errno.h>

void error_exit(void)
  {
    perror("ups");
    exit(EXIT_FAILURE);
  }

int main(void)
  {
    unsigned long long temp;
    errno=0;
    temp = strtoull("FFFFF123", NULL, 16);
    if(errno)
      {
        error_exit();
      }
    printf("DWORD=%"PRId32"\n", (int32_t) temp );
    errno=0;
    temp = strtoull("FFFFFFFFFFFFF123", NULL, 16);
    if(errno)
      {
        error_exit();
      }
    printf("QWORD=%"PRId64"\n", (int64_t) temp );

    return EXIT_SUCCESS;
  }

08-16 21:56
查看更多