C语言scanf函数奇遇记

C语言scanf函数奇遇记

作者:ocean    撰写日期:2011-11-20

博客链接:http://oceanspace.tk

 

    看《The C Programming Language》中关于scanf函数部分时随意敲了几行代码,本以为简单的不得了,都有点“不屑于”敲,却没想到这一敲竟然敲出个不小的问题,涉及到好多东西啊,哈哈!下面把我这次的经历和大家分享一下,希望也能对大家有所帮助。

一、代码实例

我当时敲的代码:

#include<stdio.h>

int main()

{

int a;

int b;

char mon[20];

int count;



count = scanf("%d,%s,%d", &a,mon,&b);

printf("%d,%s,%d\n",a,mon,b);

printf("%d\n",count);



return 0;

}

运行结果:

ocean@ocean-desktop:~/桌面$ ./re

12,fefe,45   /*这是我的输入*/

12,fefe,45,10359588

2

       结果看起来挺像我们想要的结果的,只是最后多了个奇怪的数字;但仔细看下count的值我们就纳闷了,怎么是2不是3呢?怎么scanf只读了两个值?到底怎么回事呢?先用gdb调试一下吧,看看a和mon里都是些什么。

二、GDB调试情况

(gdb) p a

$1 = 12

(gdb) p mon

$2 = "fe,45\000\377\277\245\324\025\000\060\340\021\000K\205\004\b"

       明白了吧?原来fe,45作为一个整体被存到mon里了,b根本没读到值,显示了个原内存里的乱七八糟的数值(不相信的话可以在程序开头给b赋个值,最后结果肯定是输出当初赋的值,因为根本没有给b读入新的值),scanf真的只读了两个值,所以count显示2。那为什么会这样呢?让我们来看看scanf函数的相关信息吧。

三、scanf函数工作原理

       scanf()是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。往输入流缓冲区送数据是遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区。scanf() 开始读取输入以后,会在遇到的第一个空白字符空格(blank)、制表符(tab)或者换行符(newline)处停止读取。

       格式控制字符串中有普通字符(非格式字符)时,这些字符作为输入数据的分隔符,在scanf函数读入数据时自动去掉。

       scanf()格式控制字符串中如果使用%s说明符,那么空白字符以外的所有字符都是可以接受的,所以scanf() 跳过空白字符直到遇到第一个非空白字符,然后保存再次遇到空白字符之前的所有非空白字符。这就意味着%s使scanf() 读取一个单词,也就是说,一个不包含空白字符的字符串。

       好,让我们分析下上述的结果是如何出现的吧。

四、原因分析

       首先,scanf()跳过空白字符(这里没有,因为第一个字符就是1)直到遇到一个非空白字符1,然后继续读2,读到逗号这个非数字符号时scanf知道整数读完了,将12赋给a,此时输入流缓冲区中第一个开头的字符是逗号;scanf继续读,读到逗号与格式控制字符串的逗号匹配,pass;从f继续读,一直读到下一个空白符——我们结束时敲的回车(scanf自动把这个回车符去掉了,没有送到字符串里),字符串读完了,此时输入流缓冲区里第一个开头的字符是我们敲的回车符;继续读,回车符与格式控制字符串里的逗号不批配,读取失败,不读了。   综上所述,scanf确实只读了一个整数和一个字符串,返回值是2。

       那有什么办法实现用逗号作为间隔符的情况呢?下面提供两种方法:

五、解决方法

1:

       scanf("%d,%[^,],%d", &a,mon,&b);

       printf("%d,%s,%d\n",a,mon,b);

       相关知识:scanf中一种很少见但很有用的转换字符:[...]和[ ^...]

       %[...]如果输入的字符属于方括号内字 符串中某个字符,那么就提取该字符;如果一经发现不属于就结束提取。%[^...]如果一经发现输入的字符属于方括号内字符串中某个字符,那么就结束提取;如果不属于就提取该字符。这两种方法会自动加上一个字符串结束符到已经提取的字符后面。例如:

#include<stdio.h>

main()

{

char strings[100];

scanf("%[1234567890]",strings);

printf("%s",strings);

return 0;

}

运行,输入:1234werew后,结果是:1234。

       采用这种方法,读完fefe后遇到逗号便结束字符串的读取,继续读时输入流缓冲区的逗号与格式控制字符串中逗号刚好匹配,成功!

2(不够彻底):

scanf("%d,%s ,%d", &a,mon,&b);   /*注意%s后面有个空格 */

printf("%d,%s,%d\n",a,mon,b);

并且在输入时加个空格

12,fefe ,45   /*fefe和逗号之间加个空白*/

       相关知识:当scanf()格式控制字符串中出现空白时,表示取数时跳过任何空白。

scanf读到fefe后的空格后结束字符串的读取,此时输入流缓冲区第一个字符为空格;继续读,由于格式控制字符串里有个空格,所以读取时会跳过任何空白(不信可以在fefe后面多敲几个空白试试,全都跳过,甚至连回车都跳过),读到逗号匹配成功。

转载于:https://www.cnblogs.com/happyblog/archive/2012/03/15/2398187.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495091.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PySide6 信号、槽

信号与槽的入门应用&#xff08;一&#xff09;&#xff1a;https://blog.csdn.net/jia666666/article/details/81774175 信号与槽的再细分&#xff08;二&#xff09;&#xff1a;https://blog.csdn.net/jia666666/article/details/81774858 信号与槽的高级玩法&#xff08;三…

芯片业又起波澜!博通189亿美元收购遭质疑,股价一度跌近19%

来源&#xff1a;华尔街见闻摘要&#xff1a;如果说博通上次收购高通面临的最大“对手”是特朗普政府&#xff0c;这次收购CA的“对手”可能是华尔街。如果说博通上次收购高通面临的最大“对手”是特朗普政府&#xff0c;这次收购CA的“对手”可能是华尔街。美东时间周三&#…

JavaScript常用技巧专题五

文章目录 一、使用适当的命名和注释来提高代码可读性二、优雅的写条件判断代码2.1、普通的if else2.2、三元运算符2.3、多个if else2.4、switch case2.5、对象写法2.6、Map写法 三、封装条件语句四、函数应该只做一件事五、Object.assign给默认对象赋默认值六、函数参数两个以下…

写出漂亮代码的七种方法

首先我想说明我本文阐述的是纯粹从美学的角度来写出代码&#xff0c;而非技术、逻辑等。以下为写出漂亮代码的七种方法&#xff1a; 1.尽快结束 if 语句 例如下面这个JavaScript语句&#xff0c;看起来就很恐怖&#xff1a; function findShape(flags, point, attribute, list)…

HTML 页面的生命周期、HTML 事件

From&#xff1a;https://blog.csdn.net/WuLex/article/details/101016936 1、页面生命周期 HTML页面的生命周期有以下三个重要事件&#xff0c;每个事件都有特定的用途 DOMContentLoaded &#xff1a; 浏览器已经完全加载 HTML&#xff0c;DOM 树已经构建完毕&#xff0c;js …

腾讯再次海选AI项目,1500进40,医疗零售机器人成新风向

雷刚 发自 凹非寺 量子位 报道 | 公众号 QbitAI一年一度风向标&#xff0c;腾讯又一次海选AI项目。去年第一期腾讯AI加速器结业后&#xff0c;鹅厂就马不停蹄开启了第二期报名&#xff0c;而且这一次报名企业更多、竞争更激烈、最终录取概率甚至不到3%。第二期AI加速器通过初试…

windows2000 日志

引用&#xff1a;http://os.51cto.com/art/201111/302889.htm windows 2000的日志文件通常有应用程序日志&#xff0c;安全日志、系统日志、DNS服务器日志、FTP日志、WWW日志等等&#xff0c;可能会根据服务器所开启的服务不同。当我们用流光探测时&#xff0c;比如说IPC探测&a…

The Human Touch 将人工智能和机器人用于病人工作的实际和伦理意义

来源&#xff1a;IEEE电气电子工程师学会摘要&#xff1a;我们生活在一个科幻小说可以很快成为科学事实的时代。在一代人的时间里&#xff0c;互联网已经从技术奇迹变成了实用工具&#xff0c;移动电话重新定义了我们的交流方式。我们生活在一个科幻小说可以很快成为科学事实的…

渗透测试 ( 0 ) --- XSS、CSRF、文件上传、文件包含、反序列化漏洞

漏洞数据库&#xff1a;https://www.exploit-db.com/google-hacking-database 1、渗透测试 实用 浏览器插件 chrome、edge 插件&#xff1a;搜索 cookie&#xff0c;安装 cookie editor&#xff0c;打开插件&#xff0c;可以 导出 cookie HackBar &#xff1a;Hackbar是网络安…

设为首页、加入收藏 兼容代码

一般写法&#xff1a;<a href"javascript:window.external.AddFavorite(window.location.href,document.title)">加入收藏</a><a href"javascript:void()" onclick"this.style.behaviorurl(#default#homepage);this.setHomePage(locat…

专访盛大创始人陈天桥:未来的杀手级应用必将诞生于脑科学

翻译丨于波 校对丨其奇来源丨Medium 神经科技初见陈天桥&#xff0c;他穿着带有花纹的短袖衬衫&#xff0c;休闲款式的蓝色牛仔裤&#xff0c;迷彩色的运动鞋&#xff0c;仿佛是个享受退休生活的人。过去的他可不是这样。1999年&#xff0c;陈天桥创建盛大游戏公司&#xff0c…

动手解决jar转txt软件的一个缺陷

代码&#xff1a; import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReade…

渗透测试 ( 2 ) --- 渗透测试系统、靶机、GoogleHacking、kali工具

操作系统&#xff1a;https://zhuanlan.zhihu.com/p/162865015 1、基于 Windows、Linux、Android 的渗透测试系统 1.1 基于 Linux 的系统 Kali&#xff1a;https://www.kali.org/get-kali/Parrot Security OS&#xff1a;Parrot Securitybackbox&#xff1a;https://www.backbo…

清华发布《中国AI发展报告2018》:中科院系统AI论文产出全球第一

来源&#xff1a;大数据文摘人工智能正成为全球性话题&#xff0c;各国的AI人才争夺战也正愈演愈烈。那么目前&#xff0c;人工智能在中国的发展条件如何&#xff0c;中国距离成为真正的人工智能强国到底还有多远&#xff1f;基于此&#xff0c;7月13日&#xff0c;《中国人工智…

单例模式小记【原创】

中国的历史上很少出现两个皇帝并存的时期&#xff0c;是有&#xff0c;但不多&#xff0c;那我们就认为皇帝是个单例模式&#xff0c;在这个场景中&#xff0c;有皇帝&#xff0c;有大臣&#xff0c;大臣是天天要上朝参见皇帝的&#xff0c;今天参拜的皇帝应该和昨天、前天的一…

渗透测试 ( 3 ) --- Metasploit Framework ( MSF )

白嫖 &#xff1a;https://zhuanlan.zhihu.com/p/449836479&#xff1a;http://t.zoukankan.com/hxlinux-p-15787814.html&#xff1a;https://www.52pojie.cn/thread-1586222-1-1.html Metasploit Pro 英文文档&#xff1a;https://docs.rapid7.com/metasploit/ Metasploit P…

工业4.0进行时:工业机器人为何能够快速爆发?

来源&#xff1a;资本实验室摘要&#xff1a;聚焦前沿科技创新与传统产业升级自George Devol于1961发明第一台可编程工业机器人“Unimate”以来&#xff0c;工业机器人产业已经走过了几十年的历史。到了2000年&#xff0c;全球约有74.25万台工业机器人。其中&#xff0c;超过一…

CRITICAL_SECTION 学习

// Critsetion.cpp : 定义控制台应用程序的入口点。 //#include "stdafx.h" #include <Windows.h> #include <iostream> #include <process.h> using namespace std;CRITICAL_SECTION g_cs; char name[]"zhangdongsheng";unsigned __std…

渗透测试 ( 4 ) --- Meterpreter 命令详解

From&#xff1a;https://blog.csdn.net/weixin_45605352/article/details/115824811 <<Web 安全攻防(渗透测试实战指南)>> 1、初识 Meterpreter 1.1.什么是 Meterpreter Meterpreter 是 Metasploit 框架中的一个扩展模块&#xff0c;作为溢出成功以后的攻击载荷使…

深度:中国车企遭遇最大危机!末尾淘汰赛开始【附下载】| 智东西内参

来源&#xff1a;智东西摘要&#xff1a;靠“合资”起步的中国自主品牌汽车走到了成熟期的转折点&#xff0c;面临的形势极为严峻。中国汽车自主品牌30多年的发展过程&#xff0c;从闭门造车到合资建厂&#xff0c;再到民营崛起&#xff0c;正在逐渐走向开放。经国务院批准&…