关于 scanf 和 scanf_s 的问题¶
最近作为程设基础的小教员,收到很多同学的求助,关于scanf
和scanf_s
的问题已经遇到了两次,特此写一篇博文来叙述一下这个问题。
一开始,有同学问我,
为什么会报错?我说,vs 默认强制要求使用 scanf_s 函数,于是我建议这位同学把这个错误信息关掉了。嗯。经过百度,这位同学的问题解决了。后来,又有一位同学问我,
程序为什么会崩溃?我想了想,如果 scanf_s 和 scanf 是一样的行为,这段代码是没问题的。但 scanf_s 既然安全,必然是在字符串方面做了处理。这里的 char*勉强也算一个?网上一查,果然,应该写成scanf_s("%c",&a,1);
,字符串则要写成scanf_s("%s",str,sizeof(str))
,来保证缓冲区不会溢出。
但是,这样解决这个问题又面临着不同的选择:
- 学习
scanf_s
和scanf
的不同,把所有scanf
换成scanf_s
并做相应的修改。 这样当然符合了语言进化的潮流,也会让 vs 闭嘴。但是,scanf_s 只有在 C11 标准中有,而且,根据cpprefrence.com 上关于 scanf 的描述,只有在__STDC_LIB_EXT1__
被定义且在#include<stdio.h>
之前#define __STDC_WANT_LIB_EXT1__
才能确保使用scanf_s
能使用,当然在 vs 较新版本中是默认可以使用的。但是,程设基础的作业是要丢到 oj 上的,而 oj 上的编译器不一定支持这些,所以这个选项不行。 - 坚持用
scanf
,自己按照题目要求保证缓冲区不溢出,同时让 vs 闭嘴。 网上已有教程,已经讲的很全面了,大家可以根据这个教程把 vs 教训一顿。为了能在 oj 里跑,建议用里面的方法五到八。(个人最推荐在文件头添加#define _CRT_SECURE_NO_WARNINGS
)
以后再遇到这个问题,我就丢这个连接上来就好了咯。yeah!