sscanf 对于前导零的八和九不能正常工作

sscanf does not work properly for eight and nine with leading zero

我一直在尝试从具有前导零的字符串(例如“03”)中扫描具有 sscanf() 的整数。

然而,它工作正常,但只能到“07”。以 '08' 开头的字符串将被读取为 0。

下面是我的代码和输出。感谢您的帮助!

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

int main() {

    char string_six[3] = "06";
    char string_seven[3] = "07";
    char string_eight[3] = "08";
    char string_nine[3] = "09";

    int six = -1;
    int seven = -1;
    int eight = -1;
    int nine = -1;

    sscanf(string_six, "%i", &six);
    sscanf(string_seven, "%i", &seven);
    sscanf(string_eight, "%i", &eight);
    sscanf(string_nine, "%i", &nine);

    printf("Six: %i\n",six);
    printf("Seven: %i\n",seven);
    printf("Eight: %i\n",eight);
    printf("Nine: %i\n",nine);

    return 0;    
}

输出:

Six: 6
Seven: 7
Eight: 0
Nine: 0

您需要使用转换说明符 %d 而不是 %i

来自C标准(7.21.6.2 fscanf函数)

d Matches an optionally signed decimal integer, whose format is the same as expected for the subject sequence of the strtol function with the value 10 for the base argument. The corresponding argument shall be a pointer to signed integer.

i Matches an optionally signed integer, whose format is the same as expected for the subject sequence of the strtol function with the value 0 for the base argument. The corresponding argument shall be a pointer to signed integer.

以及(7.22.1.4 strtol、strtoll、strtoul 和 strtoull 函数)

3 If the value of base is zero, the expected form of the subject sequence is that of an integer constant as described in 6.4.4.1, optionally preceded by a plus or minus sign, but not including an integer suffix.

最后(6.4.4.1 整数常量)

integer-constant:
    decimal-constant integer-suffixopt
    octal-constant integer-suffixopt
    hexadecimal-constant integer-suffixopt

"08" 被解释为 octal 数字 0,后跟一个不能作为八进制数一部分的字符。如果您这样做:

   int n;
   char c;
   sscanf("08", "%i%c", &n, &c);

你应该observe n being set to 0 and c to '8'.

此行为是设计使然:%i 在输入中接受十进制、八进制和十六进制数字,使用与 C 源代码相同的语法(即前导“0”表示八进制,前导“0x” ' 或 '0X' 表示十六进制)。

如果您不想接受八进制 或十六进制 数字,您可以使用 %d 代替; 'd'表示只接受十进制数。同样,%o 只接受八进制数(但不需要前缀“0”),%x 只接受十六进制数(但不需要前缀“0x”或“0X”)。无法让 sscanf 接受十进制和 0x-前缀十六进制,但也不接受 0-前缀八进制。

但是,因为 the *scanf functions are broken as specified and should never be used at all, what you should really be doing is using strtol with third argument 10. (Pay careful attention to the part of the strtol manpage about checking for invalid input。)(无法让 strtol 接受十进制和 0x-前缀十六进制但不接受 0-前缀八进制, 或者。)