[英]Why can't I use 'scanf_s' for reading a character and a number at once?
此代码崩溃:
scanf_s("%c %d",&ch,&x);//Run error
但是此代码有效:
scanf_s("%c",&ch);
scanf_s("%d",&x);//Run succeed
我想知道为什么第一个代码片段是错误的。
“运行错误”表示编译器发出警告,并且在运行程序输入时出了点问题
当您使用scanf_s
(与scanf
)时,您需要为%c
提供一个附加的长度参数(例如,参见microsoft关于scanf_s
本文档):
与scanf和wscanf不同,scanf_s和wscanf_s要求您为某些参数指定缓冲区大小。 指定所有c,C,s,S或字符串控制集[]参数的大小。
所以你必须写
scanf_s ("%c %d", &ch, 1, &x);
指示第一个%c
最多读取一个字符。
请注意, scanf_s("%c",&ch);
也应该发出相同的警告/错误,因为它也缺少%c
的必需长度参数。
命令scanf_s("%d",&x);
相反,可以,因为%d
不需要(不必提供)附加的长度参数。
作为斯蒂芬· scanf_s("%c %d",&ch,&x)
Stephan Lechner)答案的扩展,请考虑执行scanf_s("%c %d",&ch,&x)
时会发生什么。
从技术上讲,这是未定义的行为,因为没有为scanf_s
指定正确的参数。
但是,实际上,代码将尝试将内存中的垃圾值解释为缺少的参数。 也就是说,代码等效于以下内容:
scanf_s("%c %d", &ch, 0xf0000000, 0xdeadbeef);
这里0xf0000000
表示变量x
的地址。 scanf_s
的代码会将其解释为缓冲区大小(一个非常大的缓冲区),但这没有效果,因为%c
告诉它只能读取一个字节。 此外, 0xdeadbeef
表示垃圾,代码将其解释为写入整数结果的地址。 写入随机地址是一个很大的禁忌,因此会崩溃。
当您的代码分别读取char
和int
,它永远不会遇到写入随机地址的情况,因此一切正常,如果忽略编译器警告,您将永远不会知道您的代码有错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.