1

我一直在尝试使用sscanf()带有前导零的字符串(例如'03')扫描整数。

但是,它工作正常,但只到 '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
4

2 回答 2

5

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

来自 C 标准(7.21.6.2 fscanf 函数)

d匹配可选带符号的十进制整数,其格式与 strtol 函数的主题序列的预期格式相同, base 参数的值为 10。相应的参数应该是一个指向有符号整数的指针。

i匹配可选带符号的整数,其格式与 strtol 函数的主题序列的预期格式相同, base 参数的值为 0。相应的参数应该是一个指向有符号整数的指针。

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

3 如果 base 的值为零,则主题序列的预期形式是 6.4.4.1 中描述的整数常量,前面可选加号或减号,但不包括整数后缀。

最后(6.4.4.1 整数常量)

integer-constant:
    decimal-constant integer-suffixopt
    octal-constant integer-suffixopt
    hexadecimal-constant integer-suffixopt
于 2022-01-12T18:16:06.503 回答
2

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

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

您应该观察到设置n为 0 和c'8'.

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

如果不想接受八进制或十六进制数,可以%d改用;'d' 表示只接受十进制数字。同样,%o只接受八进制数(但不需要'0'前缀)并且%x只接受十六进制数(但不需要'0x'或'0X'前缀)。没有办法sscanf接受十进制和0x-prefix hex 但也不能接受0-prefix octal。

但是,由于函数*scanf已按规定损坏并且根本不应该使用,因此您真正应该做的是使用strtol第三个参数 10。(请注意手册页中有关检查无效输入的部分strtol。)(有没有办法strtol接受十进制和0x-prefix hex 但也不接受0-prefix octal。)

于 2022-01-12T18:35:46.270 回答