当前位置:网站首页>sscanf,sscanf_s及其相关使用方法「建议收藏」
sscanf,sscanf_s及其相关使用方法「建议收藏」
2022-07-06 21:49:00 【全栈程序员站长】
大家好,又见面了,我是全栈君。
#include<stdio.h>
定义函数 int sscanf (const char *str,const char * format,……..);
函数说明 sscanf()会将參数str的字符串依据參数format字符串来转换并格式化数据。格式转换形式请參考scanf()。
转换后的结果存于相应的參数内。
返回值 成功则返回參数数目,失败则返回-1,错误原因存于errno中。 返回0表示失败 否则。表示正确格式化数据的个数 比如:sscanf(str。”%d%d%s”, &i,&i2, &s); 假设三个变成都读入成功会返回3。 假设仅仅读入了第一个整数到i则会返回1。证明无法从str读入第二个整数。
main() { int i; unsigned int j; char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”; char s[5]; sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s); printf(“%d %d %s ”,i,j,s); }
运行 10 27 aaaaa
大家都知道sscanf是一个非常好用的函数,利用它能够从字符串中取出整数、浮点数和字符串等等。它的用法简单,特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法。这里做个简要说明吧。
1. 常见使用方法。
charstr[512]={0}; sscanf(“123456″,”%s”,str); printf(“str=%s”,str);
2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf(“123456″,”%4s”,str); printf(“str=%s”,str);
3. 取到指定字符为止的字符串。如在下例中。取遇到空格为止字符串。
sscanf(“123456abcdedf”,”%[^]”,str); printf(“str=%s”,str);
4. 取仅包括指定字符集的字符串。如在下例中,取仅包括1到9和小写字母的字符串。
sscanf(“123456abcdedfBCDEF”,”%[1-9a-z]”,str); printf(“str=%s”,str);
5. 取到指定字符集为止的字符串。如在下例中。取遇到大写字母为止的字符串。
sscanf(“123456abcdedfBCDEF”,”%[^A-Z]”,str); printf(“str=%s”,str);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
能够用例如以下代码将字符串形式的ip地址转换为四个整数:
- char * inputIp
- int ip[4];
- sscanf_s(inputIp, “%d.%d.%d.%d”, &ip[0], &ip[1],&ip[2],&ip[3]);
注意sscanf_s。当读入的类型是整数或其他长度能够确定的类型时。不能在类型后面跟上长度,可是对于字符串类型(char *)长度无法得知则必须在类型后面明白指出字符串的最大长度(即能够容纳的空间)。举比例如以下:
- // crt_sscanf_s.c
- // This program uses sscanf_s to read data items
- // from a string named tokenstring, then displays them.
- #include <stdio.h>
- #include <stdlib.h>
- int main( void )
- {
- char tokenstring[] = “15 12 14…”;
- char s[81];
- char c;
- int i;
- float fp;
- // Input various data from tokenstring:
- // max 80 character string plus NULL terminator
- sscanf_s( tokenstring, “%s”, s, _countof(s) );
- sscanf_s( tokenstring, “%c”, &c, sizeof(char) );
- sscanf_s( tokenstring, “%d”, &i );
- sscanf_s( tokenstring, “%f”, &fp );
- // Output the data read
- printf_s( “String = %s\n”, s );
- printf_s( “Character = %c\n”, c );
- printf_s( “Integer: = %d\n”, i );
- printf_s( “Real: = %f\n”, fp );
- }
对于多个字符串读入的情况。代码例如以下:
- sscanf_s(inputString, “%s.%s.%s.%s”, s1, s1.length, s2, s2.length, s3, s3.length, s4, s4.length);
sscanf 函数很好用,竟然我曾经一直不知道这个函数。近期朋友用VS2008敲代码时用到这个函数的安全版本号 sscanf_s 。却出现异常问题。无法解析字符串不说,还会崩溃。
int sscanf_s( const char *buffer, const char *format [, argument ] … );
这是MSDN里面关于函数的定义,没有继续具体查看后面的备注,以及实例的情况下。根本感觉不到sscanf 与 sscanf_s 的差别。以为仍然是像sscanf 一样使用。以致出现奇怪问题。
Example:
// crt_sscanf_s.c
// This program uses sscanf_s to read data items
// from a string named tokenstring, then displays them.
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char tokenstring[] = "15 12 14...";
char s[81];
char c;
int i;
float fp;
// Input various data from tokenstring:
// max 80 character string plus NULL terminator
sscanf_s( tokenstring, "%s", s, _countof(s) );
sscanf_s( tokenstring, "%c", &c, sizeof(char) );
sscanf_s( tokenstring, "%d", &i );
sscanf_s( tokenstring, "%f", &fp );
// Output the data read
printf_s( "String = %s\n", s );
printf_s( "Character = %c\n", c );
printf_s( "Integer: = %d\n", i );
printf_s( "Real: = %f\n", fp );
}
直到看完整个文档,看到这个实例,才发现原来还有猫腻!sscanf_s 取值的时候。须要在每一个取值后面指定取值的最大大小。
在使用VS2005编译一个程序时,出现了非常多警告,说是用的函数是不安全的。应当使用安全版本号,即函数名称添加“_s”的版本号。 警告内容: warning C4996: ‘sscanf’: This function or variable may be unsafe. Consider using sscanf_s instead. 据了解,“_s”版本号函数是微软后来对c++做得扩展。用来替代原先不安全的函数。比如:printf、scanf、strcpy、fopen等等。
具体參考: ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vccrt/html/d9568b08-9514-49cd-b3dc-2454ded195a3.htm
原来安全版本号的函数,对參数和缓冲边界做了检查,添加了返回值和抛出异常。这样添加了函数的安全性,降低了出错的几率。 同一时候这也意味着在使用这些函数时。有时你不得不输入很多其它的关于缓冲区大小的參数,多敲几下键盘能换来更少的麻烦。值得!
以下总结了sscanf的以及sscanf_s的经常用法,也体现了“_s”版本号函数与原函数的特别之处:
1、sscanf和scanf的不同是输入来源。前者是一个字符串,后者则是标准输入设备
2、sscanf的使用。以解析时间字符串为例。将字符串“2009-01-02_11:12:13”解析为整型年月日时分秒
//定义 char cc; tm tm_temp={0}; string stime(“2009-01-02_11:12:13”);
//(1) 必须严格依照分隔符形式匹配填写,若遇到不匹配项则终止解析
sscanf(stime.c_str(), “%4d-%2d-%2d_%2d:%2d:%2d”, &tm_temp.tm_year, &tm_temp.tm_mon, &tm_temp.tm_mday, &tm_temp.tm_hour, &tm_temp.tm_min, &tm_temp.tm_sec ); //(2) 能够不依照切割符号形式填写,字符数必须一致。比如能够正确解析“2009/01/02_11:12:13”
sscanf(stime.c_str(), “%4d%c%2d%c%2d%c%2d%c%2d%c%2d”, &tm_temp.tm_year, &cc, &tm_temp.tm_mon, &cc, &tm_temp.tm_mday, &cc, &tm_temp.tm_hour, &cc, &tm_temp.tm_min, &cc, &tm_temp.tm_sec ); //(3) 能够不依照切割符号形式填写,字符数必须一致。同上,%1s能够等同于%c
sscanf(stime.c_str(), “%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d”, &tm_temp.tm_year, &cc, &tm_temp.tm_mon, &cc, &tm_temp.tm_mday, &cc, &tm_temp.tm_hour, &cc, &tm_temp.tm_min, &cc, &tm_temp.tm_sec );
//(4) 能够不依照切割符形式和数量填写,类型必须一致。比如能够正确解析“2009/01/02___11:12:13” //这里使用了sscanf的正則表達式,与通用的正则表示类似但不全然同样,%*c表示忽略连续多个字符
sscanf(stime.c_str(), “%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d”, &tm_temp.tm_year, &tm_temp.tm_mon, &tm_temp.tm_mday, &tm_temp.tm_hour, &tm_temp.tm_min, &tm_temp.tm_sec ); 3、sscanf_s的使用
//定义 char cc[2]; tm tm_temp={0}; string stime(“2009-01-02_11:12:13”);
//(1) 与sscanf第一种方法同样,能够使用”%4d-%2d-%2d_%2d:%2d:%2d”格式匹配解析
sscanf_s(stime.c_str(), “%4d-%2d-%2d_%2d:%2d:%2d”, &tm_temp.tm_year, &tm_temp.tm_mon, &tm_temp.tm_mday, &tm_temp.tm_hour, &tm_temp.tm_min, &tm_temp.tm_sec ); //(2) 使用%c格式对数据解析时。必须对对应的缓冲区添加长度參数。否则将会出错
sscanf_s(stime.c_str(), “%4d%c%2d%c%2d%c%2d%c%2d%c%2d”, &tm_temp.tm_year, &cc, 1, &tm_temp.tm_mon, &cc, 1, &tm_temp.tm_mday, &cc, 1, &tm_temp.tm_hour, &cc, 1, &tm_temp.tm_min, &cc, 1, &tm_temp.tm_sec ); //(3) 使用%s格式对数据解析时。缓冲长度必须大于字符串长度,否则不予解析
sscanf_s(stime.c_str(), “%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d”, &tm_temp.tm_year, &cc, 2, &tm_temp.tm_mon, &cc, 2, &tm_temp.tm_mday, &cc, 2, &tm_temp.tm_hour, &cc, 2, &tm_temp.tm_min, &cc, 2, &tm_temp.tm_sec );
//(4) 与sscanf一样,sscanf_s相同支持正則表達式
sscanf_s(stime.c_str(), “%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d”, &tm_temp.tm_year, &tm_temp.tm_mon, &tm_temp.tm_mday, &tm_temp.tm_hour, &tm_temp.tm_min, &tm_temp.tm_sec ); 通过以上对照sscanf与sscanf_s的使用,能够看出后者对缓冲区安全有了很多其它的考虑,从而避免了很多不经意的烦恼。
大家都知道sscanf是一个非常好用的函数,利用它能够从字符串中取出整数、浮点数和字符串等等。
它的用法简单。特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。
1. 常见使用方法。
下面是引用片段: char str[512] = ; sscanf(“123456 “, “%s”, str); printf(“str=%sn”, str); |
---|
2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
下面是引用片段: sscanf(“123456 “, “%4s”, str); printf(“str=%sn”, str); |
---|
3. 取到指定字符为止的字符串。如在下例中。取遇到空格为止字符串。
下面是引用片段: sscanf(“123456 abcdedf”, “%[^ ]”, str); printf(“str=%sn”, str); |
---|
4. 取仅包括指定字符集的字符串。如在下例中。取仅包括1到9和小写字母的字符串。
下面是引用片段: sscanf(“123456abcdedfBCDEF”, “%[1-9a-z]”, str); printf(“str=%sn”, str); |
---|
5. 取到指定字符集为止的字符串。
如在下例中,取遇到大写字母为止的字符串。
下面是引用片段: sscanf(“123456abcdedfBCDEF”, “%[^A-Z]”, str); printf(“str=%sn”, str);
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/116614.html原文链接:https://javaforall.cn
边栏推荐
- Unity3D在一建筑GL材料可以改变颜色和显示样本
- How to write a resume that shines in front of another interviewer [easy to understand]
- Web service performance monitoring scheme
- 见到小叶栀子
- Use dumping to back up tidb cluster data to GCS
- 2022 electrician cup question B analysis of emergency materials distribution under 5g network environment
- Formation continue en robotique (automatisation) - 2022 -
- The root file system of buildreoot prompts "depmod:applt not found"
- 数学分析_笔记_第10章:含参变量积分
- ESG全球领导者峰会|英特尔王锐:以科技之力应对全球气候挑战
猜你喜欢
ABAP 动态内表分组循环
2022中青杯C题城市交通思路分析
Food Chem|深度学习根据成分声明准确预测食品类别和营养成分
C#使用西门子S7 协议读写PLC DB块
[OA] excel document generator: openpyxl module
[team learning] [34 sessions] Alibaba cloud Tianchi online programming training camp
深耕开发者生态,加速AI产业创新发展 英特尔携众多合作伙伴共聚
[written to the person who first published the paper] common problems in writing comprehensive scientific and Technological Papers
超越Postman,新一代国产调试工具Apifox,用起来够优雅
案例大赏:英特尔携众多合作伙伴推动多领域AI产业创新发展
随机推荐
[OA] excel document generator: openpyxl module
JetBrain Pycharm的一系列快捷键
CUDA Programming
Easycvr cannot be played using webrtc. How to solve it?
Nanopineo use development process record
機器人(自動化)課程的持續學習-2022-
测试/开发程序员怎么升职?从无到有,从薄变厚.......
Triple half circle progress bar, you can use it directly
Food Chem | in depth learning accurately predicts food categories and nutritional components based on ingredient statements
golang 压缩和解压zip文件
The most complete deployment of mongodb in history
Operational amplifier application summary 1
ABAP 动态内表分组循环
NFT meta universe chain diversified ecosystem development case
5年自动化测试,终于进字节跳动了,年薪30w其实也并非触不可及
buildroot的根文件系统提示“depmod:applt not found”
Use dumping to back up tidb cluster data to GCS
kivy教程之设置窗体大小和背景(教程含源码)
Different meat customers joined hands with Dexter to launch different hamburgers in some stores across the country
见到小叶栀子