C++ 为什么sscanf不能与布尔类型一起正常工作

C++ 为什么sscanf不能与布尔类型一起正常工作,c++,c,boolean,scanf,C++,C,Boolean,Scanf,此代码的输出: const char *buff = "*_2D 1"; char field[10]; int flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); is字段:*U 2D标志:1 但是,将int更改为bool会导致奇怪的行为: const char *buff = "*_2D 1"; char field[10]; bool flag; sscanf(

此代码的输出:

const char *buff = "*_2D 1";
char field[10];
int flag;
sscanf(buff, "%s %d", field, &flag);
printf("field:%s flag:%i\n", field, flag);
is
字段:*U 2D标志: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);
输出为
字段:标志:1


有人能解释一下这里发生了什么吗?我本以为bool会被解释为int,看起来是,但字符串的其余部分消失了。

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

< P>想象一下,如果<代码> BoOL <代码>只是一个字节,而不是<代码> int <代码>使用的四(甚至八)。然后告诉
sscanf
&flag
是指向
int
的指针,将覆盖堆栈上其他地方的三个或七个字节,这些字节可能位于
字段
变量的正上方。该空间将被0字节填充,从而有效地终止字符串。

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

sscanf
不是类型安全的;您告诉它(使用
%d
转换说明符)您提供了一个指向
int
的指针,因此它假设在那里写
int
是安全的。如果实际类型较小,则会得到未定义的行为;最有可能的情况是,其他局部变量将被覆盖,或者堆栈帧将被损坏。在这种情况下,它似乎正在用整数值
1
的零值字节覆盖
字段的开头。根据,对%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);

它会给你同样的错误。

< P>如果你使用C++(这似乎是你的评论中的例子),为什么不使用C++流代替C风格<代码> SCANF方法?< /P>
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;
const std::string buff=“*_2d1”;
std::字符串字段;
布尔标志=假;
标准::istringstream ss(浅黄色);
ss>>字段>>标志;

STD::将C++类型与C IO函数混合是一个坏主意。@ YBangGalbi:什么是C++类型?@ Salg:它也是(C99类型的别名)。但是你已经用“C”和“C++”标记了这个问题;你实际使用的是哪种语言?@Salgar:Old C还是C99?如果你包括stdbool.hy,C99就有了它。你是正确的,我没有意识到我的平台上的
sizeof(bool)
是1。谢谢:)真的,很不幸,这不是我最初写的。这就是软件。@Salgar:我非常清楚:)
bool
也不是
char
;这是一个明显的类型(假设这是C++,或者是C99和<代码> <代码>),而不保证与“代码> char < /代码>的大小相同……CONSITER是SCANSF的一个符号的一个字节(类似于char)(在STDBOOL。H,BooL只是一个TyWIFF):@不:在C99中,<代码>布尔O/COD>是一个扩展到<代码>的布尔宏< /C>;code>\u Bool
是一种内置类型,不同于
char
。C++中,<代码> BOOL是一种内置类型,再次与代码> char < />不同。
sscanf
(及其引用的
fscanf
)的规范根本没有提到
bool
(或
\u bool
)。