c - 可变顺序对 sscanf 重要吗?

标签 c scanf

我遇到了 sscanf 的一个奇怪问题,当我以特定顺序传递参数时,我可以正确读取所有值,并且如果我更改顺序,它可以正常工作。有人可以解释为什么会出现这种奇怪的行为吗?

非工作案例:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main() {
    uint8_t oct1, oct2, oct3, oct4;

    char buf[20];
    memset(buf, 0, sizeof(buf));

    sprintf(buf,"%d.%d.%d.%d", 1, 2, 3, 4);
    printf("%s\n", buf);
    int f = sscanf(buf,"%d.%d.%d.%d", &oct1, &oct2, &oct3, &oct4);
    printf("%d.%d.%d.%d \nSuccessfully read - %d\n", oct1, oct2, oct3, oct4, f);
    return 0;
}

Output:
    1.2.3.4
    0.0.0.4
    Successfully read - 4

工作案例:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main() {
    uint8_t oct1, oct2, oct3, oct4;

    char buf[20];
    memset(buf, 0, sizeof(buf));

    sprintf(buf,"%d.%d.%d.%d", 1, 2, 3, 4);
    printf("%s\n", buf);
    int f = sscanf(buf,"%d.%d.%d.%d", &oct4, &oct3, &oct2, &oct1);
    printf("%d.%d.%d.%d \nSuccessfully read - %d\n", oct1, oct2, oct3, oct4, f);
    return 0;
}
Output:
    1.2.3.4  
    4.3.2.1
    Successfully read - 4

最佳答案

uint8_t 的正确格式说明符是SCNu8来自 <inttypes.h> 的宏.用法应该是:

sscanf(buf,"%" SCNu8 ".%" SCNu8 ".%" SCNu8 ".%" SCNu8, &oct1, &oct2, 
                                                       &oct3, &oct4);

同样,SCNu32SCNu16对于 uint32_tuint16_t分别和SCNd8 , SCNd16 , SCNd32对于 int8_t , int16_tint32_t分别。

请注意,这些固定整数类型(在 C99 中引入)是可选类型。

旁白:

sprint很危险,因为它们无法防止缓冲区溢出。建议使用snprintf()相反:

snprintf(buf,sizeof buf, "%d.%d.%d.%d", 1, 2, 3, 4);

此外,memset()荷兰国际集团buf这是不必要的,因为您将立即写入它(请注意 snprintf() 总是 NUL 终止缓冲区)。

关于c - 可变顺序对 sscanf 重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34378854/

相关文章:

c - 字符串在执行中途丢失数据 C

c - 强制 scanf 使用换行符

arrays - 警告 : format ‘%s’ expects type ‘char *’ , 但参数 2 的类型为 ‘char (*)’

c - 如何检查一个变量是否在C中

python - 有没有办法直接在 python (或 Ironpython)中导入 c *.lib 而不进行任何包装?

c - 不同版本操作系统的 OpenMP 性能差异

c - 将TXT转换为BIN,并打印出BIN的内容

c++ - sscanf 无法将字符串拆分为 double 值

c - 如何在c中使用fscanf从文件中读取格式化数据

c - FTP over tcp/ip atmega 8 位微 Controller 的分段和重组