用sscanf解析输入字符串

我们平常编写的很多应用程序都会处理各种各样的输入,这些输入或来自本地文件,或来自网络,或来自用户的输入。今天,让我们来看看sscanf这个和字符串相关的函数可能给你带来的麻烦。

下面是演示代码,这段代码将一些以字符串形式保存的数据加载到程序中。这些字符串可以来自任何地方,本演示代码对字符串进行了硬编码。

 struct Data
{
char item1;
char item2;
char item3;
char item4;
}; int main()
{
Data data;
memset(&data, , sizeof(data)); char data1[] = "";
char data2[] = "";
char data3[] = "";
char data4[] = ""; sscanf_s(data4, "%d", &data.item4);
sscanf_s(data3, "%d", &data.item3);
sscanf_s(data2, "%d", &data.item2);
sscanf_s(data1, "%d", &data.item1); printf_s("item1:%d\n", data.item1);
printf_s("item2:%d\n", data.item2);
printf_s("item3:%d\n", data.item3);
printf_s("item4:%d\n", data.item4); getchar();
return ;
}

你觉得执行结果会是什么?

奇怪吗?

分析

让我们分析一下:

第19行代码将4赋值给了item4,第20行代码将3赋值给了item3, 第21行代码将2赋值给了item2, 第22行代码将1赋值给了item1。似乎没什么问题。

还是来调试下程序吧。

下面几张图片演示了程序在执行过程中的内存布局

执行第一条sscanf_s前的内存布局

执行第一条sscanf_s后的内存布局

执行第二条sscanf_s后的内存布局

执行第三条sscanf_s后的内存布局

执行第四条sscanf_s后的内存布局

到这里,相信大家都已经明白程序的输出结果为何是1,0,0,0了。

演示代码不仅发生了内存越界,而且后续所有的输入都覆盖了上一条的执行结果。

罪魁祸首就是sscanf_s中的格式字符串"%d","%d"表明将输入字符串作为一个int类型来保存到目标地址处。而演示代码的书写方式很显然不符合Data这个结构体中各成员所声明类型的要求。

将个数字符串修改为"%c"后,程序执行正确:

当然,我们其实可以在编译阶段发现这类问题

结语

通过今天这个演示,更加让自己明白了一定要多留意编译期间的警告信息,尽全力将其消灭。

本博客仅仅演示了sscanf_s这类函数的冰山一角,对于其他需要注意的地方可以参考Format Specifiers Checking

你的sscanf用对了吗的更多相关文章

  1. C语言关于利用sscanf实现字符串相加减

    #include<stdio.h>#include<string.h>void main(){ int a; int b; char str1[10] = "9999 ...

  2. sscanf提取字符串中的数据php

    1.需求 理解sscanf的作用 2.例子 $str = "age:30 weight:60kg"; sscanf($str,"age:%d weight:%dkg&qu ...

  3. sscanf与正则表达式(转)

    今天翻google reader的时候看到这样一篇文章,介绍的是sscanf的高级用法.直到今天我才知道sscanf是可以直接用正则表达式的,惭愧. 在msdn中sscanf的声明如下 int ssc ...

  4. C语言函数sscanf()的用法

    从文件读取数据是一件很麻烦的事,所幸有sscanf()函数. C语言函数sscanf()的用法 sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: int sscanf( st ...

  5. sscanf()函数的使用及其实例

    资料引自: 传送门 sscanf函数原型: Int sscanf( const char * src, const char * format, ...); int scanf( const char ...

  6. C 语言sscanf

    C语言以sscanf逗号作为分割符 ]={}; ]={}; ]={}; sscanf(],&buf_b[],&buf_b[]); printf("************** ...

  7. Babelfish(二分查找,字符串的处理略有难度,用sscanf输入)

    Babelfish Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 28581   Accepted: 12326 题目链接: ...

  8. (转)sscanf() - 从一个字符串中读进与指定格式相符的数据

    (转)sscanf() - 从一个字符串中读进与指定格式相符的数据 sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: Int sscanf( string str, stri ...

  9. sscanf函数

    sscanf函数用法举例 #include <stdio.h> #include <string.h> #define N 512 int main() { char buf[ ...

  10. hdu 1036 (I/O routines, fgets, sscanf, %02d, rounding, atoi, strtol) 分类: hdoj 2015-06-16 19:37 32人阅读 评论(0) 收藏

    thanks to http://stackoverflow.com/questions/2144459/using-scanf-to-accept-user-input and http://sta ...

随机推荐

  1. 解析xml的几种方式

    http://blog.csdn.net/smcwwh/article/details/7183869

  2. 单点登录CAS使用记(七):关于服务器超时以及客户端超时的分析

    我的预想情况 一般情况下,当用户登录一个站点后,如果长时间没有发生任何动作,当用户再次点击时,会被强制登出并且跳转到登录页面, 提醒用户重新登录.现在我已经为站点整合了CAS,并且已经实现了单点登录以 ...

  3. 高放的python学习笔记之基本语法

    python与c++的不同之处 python的语句块不是用{}括起来的而是冒号后面跟一些与比当前语句多一的tab缩进的语句. 1.定义变量 python的变量类型不需要人为指出,会根据赋值的类型决定此 ...

  4. 六种方式实现hibernate查询

    最近在学习Hibernate的基本内容,刚好在项目中有用到,基本上都是用到哪就学哪. 今天看看六种方式实现hibernate查询......... 分别是HQL查询,对象化查询Criteria方法,动 ...

  5. ie6,7下js动态加载图片不显示错误

    ie6,7下js动态加载图片不显示错误 先描述一下出现这种匪夷所思bug的背景: 我在页面加载的时候加载一堆小缩略图,<a href="javascript:void(0);" ...

  6. jQuery自学笔记(二):jQuery选择器

    一.简单选择器 ID选择器:$('#box') 元素标签名:$('div') 类选择器:$('.box') jQuery提供了length和size()两种方法查看返回的元素,可验证ID在页面只出现一 ...

  7. YOU邮件

    include("class.phpmailer.php");include("class.smtp.php");//获取一个外部文件的内容$mail      ...

  8. javascript模块

    //使用模块 template = {}; template.createObj = (function(){ //私有成员 var _age = ""; var _name = ...

  9. 使用 phpMyAdmin无法登录mysql的问题

    今天使用使用phpmyadmin时出现了以下错误: (1)第一次时: 当配置文件config.inc.php里的配置项是: $cfg['Servers'][$i]['host'] = 'localho ...

  10. DEDE常见问题(转)

    问题1. 把数据保存到数据库附加表 `dede_addonvisa` 时出错,请把相关信息提交给DedeCms官方.Unknown column 'redirecturl' in 'field lis ...