[英]Why can't I use 'scanf_s' for reading a character and a number at once?
This code crashes: 此代码崩溃:
scanf_s("%c %d",&ch,&x);//Run error
But this code works: 但是此代码有效:
scanf_s("%c",&ch);
scanf_s("%d",&x);//Run succeed
I want to know why the first code fragment is wrong. 我想知道为什么第一个代码片段是错误的。
'run error' means The compiler has a warning and something is wrong when I run the program input “运行错误”表示编译器发出警告,并且在运行程序输入时出了点问题
As you are using scanf_s
(in contrast to scanf
), you need to provide an additional length parameter for %c
(cf, for example, this document from microsoft regarding scanf_s
): 当您使用
scanf_s
(与scanf
)时,您需要为%c
提供一个附加的长度参数(例如,参见microsoft关于scanf_s
本文档):
Unlike scanf and wscanf, scanf_s and wscanf_s require you to specify buffer sizes for some parameters.
与scanf和wscanf不同,scanf_s和wscanf_s要求您为某些参数指定缓冲区大小。 Specify the sizes for all c, C, s, S, or string control set [] parameters.
指定所有c,C,s,S或字符串控制集[]参数的大小。
So you will have to write 所以你必须写
scanf_s ("%c %d", &ch, 1, &x);
indicating that the first %c
shall read at most one character. 指示第一个
%c
最多读取一个字符。
Note that scanf_s("%c",&ch);
请注意,
scanf_s("%c",&ch);
should issue the same warning/error as it lacks the mandatory length parameter for %c
, too. 也应该发出相同的警告/错误,因为它也缺少
%c
的必需长度参数。
Command scanf_s("%d",&x);
命令
scanf_s("%d",&x);
, in contrast, is OK as %d
does not require (must not get provided) an additional length parameter. 相反,可以,因为
%d
不需要(不必提供)附加的长度参数。
I assume you are running MSVC, which gives an error if you use scanf
instead of scanf_s
. 我假设您正在运行MSVC,如果您使用
scanf
而不是scanf_s
, scanf_s
出现错误。 I also assume you want to use the former and not the latter. 我还假设您要使用前者而不是后者。 To disable the error, go to Project menu -> [Project name] Properties -> C/C++ -> Preprocessor.
要禁用该错误,请转到项目菜单-> [项目名称]属性-> C / C ++->预处理程序。 To the "Preprocessor Definitions" field, add the macro
_CRT_SECURE_NO_WARNINGS
. 在“预处理程序定义”字段中,添加宏
_CRT_SECURE_NO_WARNINGS
。 Then click "Apply." 然后点击“应用”。
Now you should be able to use scanf
as you would on any other compiler/IDE. 现在,您应该能够像在其他任何编译器/ IDE上一样使用
scanf
。
As an expansion of the answer by Stephan Lechner , consider what happens when executing scanf_s("%c %d",&ch,&x)
. 作为斯蒂芬·
scanf_s("%c %d",&ch,&x)
Stephan Lechner)答案的扩展,请考虑执行scanf_s("%c %d",&ch,&x)
时会发生什么。
Technically, it's undefined behavior because you didn't specify the correct parameters to scanf_s
. 从技术上讲,这是未定义的行为,因为没有为
scanf_s
指定正确的参数。
However, practically, the code will try to interpret junk values in the memory as missing parameters. 但是,实际上,代码将尝试将内存中的垃圾值解释为缺少的参数。 That is, the code is equivalent to something like this:
也就是说,代码等效于以下内容:
scanf_s("%c %d", &ch, 0xf0000000, 0xdeadbeef);
Here 0xf0000000
represents the address of the variable x
. 这里
0xf0000000
表示变量x
的地址。 The code of scanf_s
will interpret it as buffer size (a very large buffer), but this has no effect because %c
tells it to read just one byte. scanf_s
的代码会将其解释为缓冲区大小(一个非常大的缓冲区),但这没有效果,因为%c
告诉它只能读取一个字节。 Further, 0xdeadbeef
represents junk, and the code interprets it as an address to write your integer result. 此外,
0xdeadbeef
表示垃圾,代码将其解释为写入整数结果的地址。 Writing to random addresses is a big no-no, so it crashes. 写入随机地址是一个很大的禁忌,因此会崩溃。
When your code reads the char
and the int
separately, it never encounters writing to a random address, so everything works well, and if you ignore compiler warnings, you never know that your code is buggy. 当您的代码分别读取
char
和int
,它永远不会遇到写入随机地址的情况,因此一切正常,如果忽略编译器警告,您将永远不会知道您的代码有错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.