scanf与scanf_s
scanf的使用
使用scanf需要记住下面两条简单规则:
- 如果使用scanf来读取某种基本变量类型(%d,%c,%f,%lf)的值,请在变量名之前加上一个&
- 如果使用scanf把一个字符串(%s)读进一个字符数组中,应不要使用&
scanf与空白字符(空格、换行符和制表符)
scanf函数使用空白字符(空格、换行符和制表符)来决定怎样把输入分成几个字段。唯一的例外就是%c,即使下一个字符是空白字符,它也会读取那个字符(即读取字符不忽略空白字符)。
实际上,scanf不是C最常用的输入函数,但是他的用途很多。而getchar和gets(gets(s)没有指明读取的最大字符数,存在缓冲区溢出漏洞,不推荐使用。现多使用fgets(s,MAXN,stdin)代替),它们更适用于读取一个字符和读取包含空格的字符串。
scanf的返回值
scanf 函数是有返回值的,它的返回值可以分成三种情况
1) 正整数,表示成功读入项目的个数。例如执行 scanf("%d%d", &a, &b);
如果用户输入"3 4",可以正确输入,返回2(正确输入了两个变量);
如果用户输入"3,4",可以正确输入a,无法输入b,返回1(正确输入了一个变量)。
2) ,表示没有读取任何项目,例如当它期望一个数字而我们却键入了一个非数字字符串时就会发生这种情况。如上例,用户如果输入",3 4",则返回0。
3) EOF,这是在stdio.h里面定义的特殊值(一般#define指令把EOF的值定义为-1),表示输入流已经结束。在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复2次),就表示输入结束;Linux/Unix下使用CTRL+D表示输入结束。
所以可以使用下面的代码来处理输入:
while (scanf("%s %c %c", str, &oldchar, &newchar) == ) /* 或!= EOF , 但前者更好 */
{
; //处理
}
为什么前面 scanf 的格式串里面,%s和%c中间需要空格呢?
那是因为如果没空格的话。。。oldchar输入的就是空格了= =.
顺便说一下,printf的返回值是输出的字符数,例如,printf("1234")的返回值是4,而printf("1234\n")的返回值是5。
scanf 和 scanf_s
- scanf()函数是标准C中提供的标准输入函数,用以用户输入数据
- scanf_s()函数是Microsoft公司Visual Studio开发工具提供的一个与scanf()功能相同的安全标准输入函数
从vc++2005开始,VS系统提供了scanf_s()。在调用该函数时,必须提供一个数字以表明最多读取多少位字符。
原因和区别
scanf()在读取数据时不检查边界,所以可能会造成内存访问越界:
例如:分配了5字节的空间但是用户输入了10字节,就会导致scanf()读到10个字节
char buf[]={'\0'};
scanf("%s", buf);
如果输入1234567890,则5以后的部分会被写到别的变量所在的空间上去,从而可能会导致程序运行异常。
以上代码如果用scanf_s()则可避免此问题:
char buf[]={'\0'};
scanf_s("%s",buf,); //最多读取4个字符,因为buf[4]要放'\0'
如果输入1234567890,则buf只会接受前4个字符
注: scanf_s最后一个参数n是接收缓冲区的大小(即buf的容量),表示最多读取n-1个字符.
PS: 很多带“_s”后缀的函数是为了让原版函数更安全,传入一个和参数有关的大小值,避免引用到不存在的元素,防止hacker利用原版的不安全性(漏洞)黑掉系统。
scanf与scanf_s的更多相关文章
- C语言杂谈(一)scanf()、scanf_s()与错误 C4996
错误 C4996 初学C语言时,第一个接触到的I/O函数便是scanf()了.但在高版本的 Visual Studio (包括但不限于2015.2013.2012)编译代码时,却会出现意想不到的错误. ...
- scanf与scanf_s的区别
scanf()函数是标准C中提供的标准输入函数,用以用户输入数据 scanf_s()函数是Microsoft公司VS开发工具提供的一个功能相同的安全标准输入函数,从vc++2005开始,VS系统提供了 ...
- scanf和scanf_s在VS2013中的使用
转载:https://www.cnblogs.com/liuchaojiayou/p/4418215.html 在VS2013中,每次使用scanf都会报错:This function or vari ...
- scanf()和scanf_s()
在最初的C语言中,原版的输入就是scanf("<格式化字符串>",<地址表>) ANSI C中没有scanf_s(),只有scanf(),scanf()在读 ...
- C语言中的scanf与scanf_s 以及循环输入的问题解决
Scanf 在标准C中,scanf提供了键盘输入功能. scanf函数是一个标准库函数,它的函数原型在头文件“stdio.h”中.与printf函数相同,C语言也允许在使用scanf函数之前不必包含s ...
- 在C语言中使用scanf语句时遇到的问题总结
在使用visual studio2013编写c语言代码时,遇到了这样的几个小问题,进行如下的总结. 1, 关于使用scanf语句报错的解决方案1 #include <stdio.h> in ...
- printf和scanf整理(后续填补)
scanf和printf头文件:<stdio.h> 1.%d.%3d.%03d.%-3d区分 %d:以十进制形式输出整数(int) %3d:指定宽度为3,不足的左边补空格 %03d:一种左 ...
- vs2017中的scanf_s
在visual studio 2017中格式化输入函数不同于其他c/c++编译器使用scanf,而是使用scanf_s. scanf_s相比较于scanf来说更安全,因为使用scanf_s函数需要有一 ...
- 【九度OJ】题目1096-二分查找
题目1069:查找学生信息 这篇文章中提到的问题主要是由于调试平台Visual Studio和测试平台Online Judge的一些小差异,造成在Visual Studio中调试通过的代码,在输入OJ ...
随机推荐
- Cryptography加密和解密
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Se ...
- 解决magento新闻邮件发送一直处于“正在发送”状态问题
今天在弄magento新闻邮件发送时候发现,单个邮件发送完全没有问题,但是新闻邮件订阅死活都不成功,国内国外的帖子都翻了一遍没有用,最后还是得靠自己了,于是开始慢慢找问题 首先想到是不是cront ...
- Day04_JAVA语言基础第四天
1.循环(掌握) 1.什么时候使用(理解) 如果我们发现有很多重复内容的时候就要使用循环 2.好处(理解) 让我们的代码看起来更精炼了 3.循环的组成(理解) 1 初始化条件:一般定义的是一个初始变量 ...
- 【Repost】A Practical Intro to Data Science
Are you a interested in taking a course with us? Learn about our programs or contact us at hello@zip ...
- Intent传输包含对象的List集合
这个其实也比较简单,我也是参考了网上的一些例子,不过我写的这个小例子亲测可用.用实现Serializable接口的方式实现. 就是说,你的list集合中的对象必须先实现Serializable接口,其 ...
- 快速对字符转义,避免跨站攻击XSS
XSS已经成为非常流行的网站攻击方式,为了安全起见,尽量避免用户的输入.可是有些情况下不仅不避免,反而要求鼓励输入,比如写博客.博客园开放性很高,可以运行手写的JS.之前比较著名的例子就是,凡是看到某 ...
- Codeforces Round #365 (Div. 2) B 前缀和
B. Mishka and trip time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Spring+SpringMVC+Mybatis+ehcache
http://www.tuicool.com/articles/myeANv http://www.mamicode.com/info-detail-1151624.html
- MySQL二进制日志的备份和恢复
二进制日志:记录数据库修改的相关操作,作用是即时点回复,主从复制 可以按时间滚动,也可以按大小滚动 server-id:服务器身份标识 一.二进制文件的删除方法,千万不要手动删除 PURGE BINA ...
- Codeforces Round #126 (Div. 2)
A. Cinema 假设当前要的位置为\((x, y)\),如果枚举答案的横坐标,那么每次找离\(y\)最近的纵坐标. 如果占用了位置\((x,y)\),需要要更新第\(x\)行的信息,而占用位置\( ...