使用scanf读取无符号字符

24

我试图使用这段代码读取 0 到 255 之间的数值(unsigned char)。

#include<stdio.h>
int main(void)
{
    unsigned char value;

    /* To read the numbers between 0 to 255 */
    printf("Please enter a number between 0 and 255 \n");
    scanf("%u",&value);
    printf("The value is %u \n",value);

    return 0;
}

正如预期的那样,我遇到了以下编译器警告:

warning: format ‘%u’ expects type ‘unsigned int *’, but argument 2 has type ‘unsigned char *’

这是我运行此程序的输出。

Please enter a number between 0 and 255
45
The value is 45 
Segmentation fault

我在运行此代码时遇到了分段错误。

使用 scanf 读取 unsigned char 值的最佳方法是什么?


13
实际上,%hhu 是用于 unsigned char 数据类型的。 - Joe
@TJD。我不想读取一个字符,我想读取0到255之间的值。 - user1293997
你可能想要编写一个答案并接受它(假设@Joe不感兴趣)。目前唯一存在的答案是相当不正确的。 - user4815162342
2个回答

44

%u 格式说明符需要一个整数,但当将其读入到 unsigned char 中时会导致未定义的行为。您需要使用 unsigned char 格式说明符 %hhu


这真的很好 - 但是很遗憾gcc在C89/C90模式下抱怨 - 而且进一步地,据我所知,ms也抱怨:%hhu在C99之前不受支持。 - Bastian Ebeling
1
@BastianEbeling 是的,在这里(http://www.cplusplus.com/reference/cstdio/scanf/) hh 被标记为黄色,这意味着它自 C99 以来才被引入。我想知道如何在 C89 中读取它。 - phuclv
1
下面有一个示例,现已删除,其中使用了 getchar() - Joe
为什么那个getchar()的例子被删除了,是因为离题了吗? - grenix

2

对于C99之前的版本,我建议编写一个额外的函数来避免由于scanf的未定义行为而导致的段错误。

方法:

#include<stdio.h>
int my_scanf_to_uchar(unsigned char *puchar)
{
  int retval;
  unsigned int uiTemp;
  retval = scanf("%u", &uiTemp);
  if (retval == 1)   
  {
    if (uiTemp < 256) {
      *puchar = uiTemp;
    }
    else {
      retval = 0; //maybe better something like EINVAL
    }
  }
  return retval; 
}

然后将 scanf("%u", 替换为 my_scanf_to_uchar(

希望这不是离题,因为我仍然使用了 scanf 而不是其他函数,比如 getchar :)

另一种方法(无需额外函数)

if (scanf("%u", &uiTemp) == 1 && uiTemp < 256) { value = uitemp; }
else {/* Do something for conversion error */}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接