为什么sscanf在bool类型下无法正常工作

这段代码的输出:

const char *buff = "*_2D 1"; char field[10]; int flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); 

field:*_2D flag:1

但是通过将int更改为bool导致奇怪的行为:

 const char *buff = "*_2D 1"; char field[10]; bool flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); 

输出为field: flag:1

任何人都可以解释这里发生的事情吗? 我会认为bool会被解释为一个int,它似乎是,但字符串的其余部分消失了。

想象一下,如果bool只是一个字节,而不是int使用的四个(甚至八个)。 然后告诉sscanf &flag是指向int的指针将最终覆盖堆栈中其他地方的三个或七个字节 – 这可能正好在你的field变量之上。 该空间将填充0个字节,有效地终止您的字符串。

boolint的单独类型,可能是单个字节(在大多数常见平台上小于int )。

sscanf不是类型安全的; 你告诉它(使用%d转换说明符)你提供了一个指向int的指针,因此它假定在那里编写一个int是安全的。 如果实际类型较小,那么你将得到未定义的行为; 最有可能的是,其他局部变量将被覆盖,或者堆栈帧将被破坏。 在这种情况下,它看起来像是用整数值1的零值字节覆盖field的开头。

可能是因为sizeof(bool)有时是1 ? 所以,我不太了解C ++,但在C中,这将是未定义的行为。

根据sscanf的规范 ,%d的描述是:

匹配可选带符号的十进制整数…如果没有大小修饰符,应用程序应确保相应的参数是指向int的指针。

也是从同一规格,

如果转换结果无法在提供的空间中表示,则行为未定义。

由于sizeof(bool)

sscanf函数失败,因为bool不是int而是char

试试这个:

 const char *buff = "*_2D 1"; char field[10]; char flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); 

它会给你同样的错误。

如果您正在使用C ++(您的评论中似乎就是这种情况),为什么不使用C ++流而不是C风格的scanf方法呢?

 const std::string buff = "*_2D 1"; std::string field; bool flag = false; std::istringstream ss(buff); ss >> field >> flag; std::cout << "field:" << field << " flag:" << flag << std::endl;