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

时间:2011-07-14 12:57:10

标签: 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);

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,它似乎是,但字符串的其余部分消失了。

6 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

根据spec for sscanf,%d的描述是:

  
    

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

  

同样来自同一规范,

  
    

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

  

由于sizeof(bool)< sizeof(int),你处于可怕的Undefined Behavior区域,任何事情都可能发生。

答案 4 :(得分:0)

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);

它会给你同样的错误。

答案 5 :(得分:0)

如果您正在使用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;