scanf(“%d”,char *) – char-as-int格式字符串?

char-as-number的格式字符串修饰符是什么?

我想使用sscanf读取一个永远不会超过255(实际上更少)的数字到一个unsigned char类型变量中。

使用典型

char source[] = "x32"; char separator; unsigned char dest; int len; len = sscanf(source,"%c%d",&separator,&dest); // validate and proceed... 

我收到了预期的警告:sscanf的参数4是char *类型,int *是预期的。

据我了解的规格,char没有修饰符(比如%sd表示简短,或%lld表示64位长)

  • 危险吗? (溢出只会溢出(翻转)变量,还是会在分配的空间外写?)
  • 有没有比分配临时int变量更美妙的方法?
  • ……或者你会建议一个完全不同的方法吗?

您可以在glibc的scanf()下使用%hhd ,MSVC似乎不直接支持整数存储到char中(有关支持的转换的更多信息,请参阅MSDN scanf Width Specification )

使用它是危险的。 由于存在从unsigned char *到int *的隐式转换,如果该数字大于0xFF,它将使用堆栈中变量旁边的字节(最大3)并破坏它们的值。

%hhd的问题在于,取决于int的大小(不一定是4个字节),它可能不是1个字节。

似乎sscanf不支持将数字存储到char中,我建议你使用int代替。 虽然如果你想让char翻转,你可以在之后将int转换为char,如:

 int dest; int len; len = sscanf(source,"%c%d",&separator,&dest); dest = (unsigned char)dest; 

我想使用sscanf读取一个永远不会超过255(实际上更少)的数字到一个unsigned char类型变量中。

在大多数情况下,使用char作为整数可以节省很少的成本。

它通常依赖于体系结构和编译器,但是大多数现代CPU在处理与寄存器大小不同的数据类型方面并不是很好。 (值得注意的例外是64位arch上的32位int。)

在这里添加对非CPU字对齐的内存访问的惩罚(不要问我为什么CPU这样做)char的使用应限于当真正需要char或内存消耗时需要考虑的情况。

这是不可能的。

读取整数时,sscanf永远不会写单个字节。

如果将指向单个已分配字节的指针作为指向int的指针传递,则将超出范围。 由于默认对齐,这可能是好的,但你不应该依赖它。

创建一个临时的。 这样你也可以运行时检查它。

可能最简单的方法是将数字简单地加载到一个临时整数中,并且只有当它在所需的边界内时才存储它。 (你可能需要像unsigned char result = tempInt & 0xFF;

这很危险。 Scanf将在字符大小的变量上写入整数大小的值。 在你的例子中(最有可能)除非你重组你的堆栈变量,否则什么都不会发生(scanf会在尝试写整数大小的“dest”时部分覆盖len,但是它会返回正确的“len”并用“right”值覆盖它)。

相反,做“正确的事情”而不是依赖于编译器的情绪:

  char source[] = "x32"; char separator; unsigned char dest; int temp; int len; len = sscanf(source,"%c%d",&separator,&temp); // validate and proceed... if (temp>=YOUR_MIN_VALUE && temp<=YOUR_MAX_VALUE) { dest = (unsigned char)temp; } else { // validation failed }