当前位置:网站首页>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
边栏推荐
- EasyCVR无法使用WebRTC进行播放,该如何解决?
- [team learning] [34 issues] scratch (Level 2)
- [coded font series] opendyslexic font
- Five years of automated testing, and finally into the ByteDance, the annual salary of 30W is not out of reach
- NTU notes 6422quiz review (1-3 sections)
- How to write a resume that shines in front of another interviewer [easy to understand]
- 【刷题记录】2. 两数相加
- [OA] excel document generator: openpyxl module
- How do test / development programmers get promoted? From nothing, from thin to thick
- 这项15年前的「超前」技术设计,让CPU在AI推理中大放光彩
猜你喜欢
Web service performance monitoring scheme
[written to the person who first published the paper] common problems in writing comprehensive scientific and Technological Papers
Easycvr cannot be played using webrtc. How to solve it?
SSM+JSP实现企业管理系统(OA管理系统源码+数据库+文档+PPT)
C#使用西门子S7 协议读写PLC DB块
Food Chem | in depth learning accurately predicts food categories and nutritional components based on ingredient statements
Collection of idea gradle Lombok errors
Digital chemical plants realize the coexistence of advantages of high quality, low cost and fast efficiency
The most complete deployment of mongodb in history
图灵诞辰110周年,智能机器预言成真了吗?
随机推荐
The root file system of buildreoot prompts "depmod:applt not found"
见到小叶栀子
Class constant pool and runtime constant pool
史上最全MongoDB之部署篇
Antd comment recursive loop comment
leetcode 53. Maximum subarray maximum subarray sum (medium)
[team learning] [phase 34] Baidu PaddlePaddle AI talent Creation Camp
UltraEdit-32 warm prompt: right association, cancel bak file [easy to understand]
ABAP Dynamic Inner table Group cycle
这项15年前的「超前」技术设计,让CPU在AI推理中大放光彩
Dab-detr: dynamic anchor boxes are better queries for Detr translation
Golang compresses and decompresses zip files
[ArcGIS tutorial] thematic map production - population density distribution map - population density analysis
vim —- 自己主动的按钮indent该命令「建议收藏」
Different meat customers joined hands with Dexter to launch different hamburgers in some stores across the country
Easycvr cannot be played using webrtc. How to solve it?
[system management] clear the icon cache of deleted programs in the taskbar
Collection of idea gradle Lombok errors
leetcode 53. Maximum Subarray 最大子数组和(中等)
MySQL data loss, analyze binlog log file