为什么sscanf不能正常工作与bool类型

Why does sscanf not work properly with a bool type

本文关键字:工作 bool 类型 sscanf 不能 常工作 为什么      更新时间:2023-10-16

代码的输出:

const char *buff = "*_2D 1";
char field[10];
int flag;
sscanf(buff, "%s %d", field, &flag);
printf("field:%s flag:%in", 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:%in", 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的指针。

同样来自同一规范,

如果转换的结果不能在提供的空格中表示,则该行为未定义。

Since sizeof(bool) <sizeof(int),你就进入了可怕的未定义行为区,任何事情都有可能发生。>

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

试试这个:

const char *buff = "*_2D 1";
char field[10];
char flag;
sscanf(buff, "%s %d", field, &flag);
printf("field:%s flag:%in", 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;