谁能说说sprintf的用法函数的用法

??.._Other(5)
头文件:#include &stdio.h&sprintf()函数用于将格式化的数据写入字符串,其原型为: int sprintf(char *str, char * format [, argument, ...]);【参数】str为要写入的字符串;format为格式化字符串,与printf()函数相同;argument为变量。除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数--格式化字符串--上。 printf()和sprintf()都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。sprintf()最常见的应用之一莫过于把整数打印到字符串中,如:sprintf(s, &%d&, 123); //把整数123打印成一个字符串保存在s中,sprintf(s, &%8x&, 4567); //小写16进制,宽度占8个位置,右对齐。sprintf的作用是将一个格式化的字符串输出到一个目的字符串中,而printf是将一个格式化的字符串输出到屏幕。sprintf的第一个参数应该是目的字符串,如果不指定这个参数,执行过程中出现 &该程序产生非法操作,即将被关闭....&的提示。sprintf()会根据参数format 字符串来转换并格式化数据,然后将结果复制到参数str 所指的字符串数组,直到出现字符串结束('\0')为止。关于参数format 字符串的格式请参考printf()。【返回值】成功则返回参数str 字符串长度,失败则返回-1,错误原因存于errno 中。注意:C语言对数组进行操作时并不检测数组的长度,如果str的长度不够,sprintf()很容易造成缓冲区溢出,带来意想不到的后果
例题看Uva 725
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7299次
积分:1141
积分:1141
排名:千里之外
原创:103篇
转载:13篇
(2)(33)(7)(23)(22)(1)(6)(21)(2)(2)关于sprintf();函数的功能及用法。一个很有用的函数。_easyx吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:6,279贴子:
关于sprintf();函数的功能及用法。一个很有用的函数。收藏
字串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通常用眼睛再把出错的代码多看几眼就看出来了。编辑本段函数简介函数功能把格式化的数据写入某个字符串缓冲区。头文件stdio.h函数原型int sprintf( char *buffer, const char *format, [ argument] … );参数列表buffer:char型指针,指向将要写入的字符串的缓冲区。format:格式化字符串。[argument]...:可选参数,可以是任何类型的数据。返回值:字符串长度(strlen)相关函数int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format, [argument] ... );int _sprintf_s_l(char *buffer,size_t sizeOfBuffer,const char *format,locale_t locale ,[argument] ... );int swprintf_s(wchar_t *buffer,size_t sizeOfBuffer,const wchar_t *format ,[argument]...);int _swprintf_s_l(wchar_t *buffer,size_t sizeOfBuffer,const wchar_t *format,locale_t locale ,[argument]…);template &size_t size&int sprintf_s(char (&buffer)[size],const char *format, [argument] ... ); //仅存在于C++template &size_t size&int swprintf_s(wchar_t (&buffer)[size],const wchar_t *format ,[argument]...); //仅存在于C++编辑本段参数说明及应用举例sprintf格式的规格如下所示。[]中的部分是可选的。%[指定参数][标识符][宽度][.精度]指示符若想输出`%'本身时, 请使用`%%'处理。1. 处理字符方向。负号时表示从后向前处理。2. 填空字元。 0 的话表示空格填 0;空格是内定值,表示空格就放着。3. 字符总宽度。为最小宽度。4. 精确度。指在小数点后的浮点数位数。=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-转换字符=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-%% 印出百分比符号,不转换。%c 整数转成对应的 ASCII 字元。%d 整数转成十进位。%f 倍精确度数字转成浮点数。%o 整数转成八进位。%s 整数转成字符串。%x 整数转成小写十六进位。%X 整数转成大写十六进位。=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-$money = 123.1$formatted = sprintf ("%06.2f", $money); // 此时变数 $ formatted 值为 "123.10"$formatted = sprintf ("%08.2f", $money); // 此时变数 $ formatted 值为 "00123.10"$formatted = sprintf ("%-08.2f", $money); // 此时变数 $ formatted 值为 "123.1000"$formatted = sprintf ("%.2f%%", 0.95 * 100); // 格式化为百分比%08.2f 解释:%开始符0是 "填空字元" 表示,如果长度不足时就用0来填满。8格式化后总长度2f小数位长度,即2位第3行值为"00123.10" 解释:因为2f是(2位)+小数点符号(1位)+前面123(3位)=6位,总长度为8位,故前面用[填空字元]0表示,即00123.10第4行值为"123.1000" 解释:-号为反向操作,然后填空字元0添加在最后面了/********************************************************以下选自《CSDN 社区电子杂志——C/C++杂志》*********************************************************/在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。sprintf 是个变参函数,定义如下:int sprintf( char *buffer, const char *format [, argument] ... );除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:格式化字符串上。printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。格式化数字字符串sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以,sprintf 在大多数场合可以替代itoa。如://把整数123 打印成一个字符串保存在s 中。sprintf(s, "%d", 123); //产生"123"可以指定宽度,不足的左边补空格:sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"当然也可以左对齐:sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"也可以按照16 进制打印:sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。sprintf(s, "%08X", 4567); //产生:""上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。这里要注意一个符号扩展的问题:比如,假如我们想打印短整数(short)-1 的内存16 进制表示形式,在Win32 平台上,一个short 型占2 个字节,所以我们自然希望用4 个16 进制数字来打印它:short si = -1;sprintf(s, "%04X", si);产生“FFFFFFFF”,怎么回事?因为spritnf 是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈时被压进来的到底是个4 字节的整数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32 位的整数-1,打印时4 个位置不够了,就把32 位整数-1 的8 位16 进制都打印出来了。如果你想看si 的本来面目,那么就应该让编译器做0 扩展而不是符号扩展(扩展时二进制左边补0 而不是补符号位):sprintf(s, "%04X", (unsigned short)si);就可以了。或者:unsigned short si = -1;sprintf(s, "%04X", si);sprintf 和printf 还可以按8 进制打印整数字符串,使用”%o”。注意8 进制和16 进制都不会打印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16 进制或8 进制表示。控制浮点数打印格式浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”%f”控制,默认保留小数点后6 位数字,比如:sprintf(s, "%f", 3.1415926); //产生"3.141593"但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m /nf”格式,其中m 表示打印的宽度,n 表示小数点后的位数。比如:sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"注意一个问题,你猜int i = 100;sprintf(s, "%.2f", i);会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:sprintf(s, "%.2f", (double)i);第一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调用者并不知道跟i相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当年被压入栈里的是个整数,于是可怜的保存整数i 的那4 个字节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。不过,如果有人有兴趣使用手工编码一个浮点数,那么倒可以使用这种方法来检验一下你手工编排的结果是否正确。字符/Ascii 码对照我们知道,在C/C++语言中,char 也是一种普通的scalable 类型,除了字长之外,它与short,int,long 这些类型没有本质区别,只不过被大家习惯用来表示字符和字符串而已。(或许当年该把这个类型叫做“byte”,然后现在就可以根据实际情况,使用byte 或short 来把char 通过typedef 定义出来,这样更合适些)于是,使用”%d”或者”%x”打印一个字符,便能得出它的10 进制或16 进制的ASCII 码;反过来,使用”%c”打印一个整数,便可以看到它所对应的ASCII字符。以下程序段把所有可见字符的ASCII 码对照表打印到屏幕上(这里采用printf,注意”#”与”%X”合用时自动为16 进制数增加”0X”前缀):for(int i = 32; i & 127; i++) {printf("[ %c ]: %3d 0x%#04X\n", i, i, i);}连接字符串sprintf 的格式控制串中既然可以插入各种东西,并最终把它们“连成一串”,自然也就能够连接字符串,从而在许多场合可以替代strcat,但sprintf 能够一次连接多个字符串(自然也可以同时在它们中间插入别的内容,总之非常灵活)。比如:char* who = "I";char* whom = "CSDN";sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "strcat 只能连接字符串(一段以'\0'结尾的字符数组或叫做字符缓冲,null-terminated-string),但有时我们有两段字符缓冲区,他们并不是以 ’’结尾。比如许多从第三方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’’来结尾。如果直接连接,不管是sprintf 还是strcat 肯定会导致非法内存操作,而strncat 也至少要求第一个参数是个null-terminated-string,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数时可以指定宽度,字符串也一样的。比如:char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};如果:sprintf(s, "%s%s", a1, a2); //Don't do that!十有八九要出问题了。是否可以改成:sprintf(s, "%7s%7s", a1, a2);也没好到哪儿去,正确的应该是:sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"这可以类比打印浮点数的”%m/nf”,在”%m.ns”中,m 表示占用宽度(字符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分字符:sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组中的几个字符,这种动态的宽度/精度设置功能在sprintf 的实现中也被考虑到了,sprintf 采用”*”来占用一个本来需要一个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的变量一样被提供出来,于是,上面的例子可以变成:sprintf(s, "%.*s%.*s", 7, a1, 7, a2);或者:sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:sprintf(s, "%-*d", 4, 'A'); //产生"65 "sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0Xsprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"打印地址信息有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个32 位的数,你完全可以使用打印无符号整数的”%u”把他们打印出来:sprintf(s, "%u", &i);不过通常人们还是喜欢使用16 进制而不是10 进制来显示一个地址:sprintf(s, "%08X", &i);然而,这些都是间接的方法,对于地址打印,sprintf 提供了专门的”%p”:sprintf(s, "%p", &i);我觉得它实际上就相当于:sprintf(s, "%0*x", 2 * sizeof(void *), &i);利用sprintf 的返回值较少有人注意printf/sprintf 函数的返回值,但有时它却是有用的,spritnf 返回了本次函数调用最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf 调用结束以后,你无须再调用一次strlen 便已经知道了结果字符串的长度。如:int len = sprintf(s, "%d", i);对于正整数来说,len 便等于整数i 的10 进制位数。下面的是个完整的例子,产生10 个[0, 100)之间的随机数,并将他们打印到一个字符数组s 中,以逗号分隔开。#include &stdio.h&#include &stdlib.h&#include &time.h&int main() {srand(time(0));char s[64];int offset = 0;for(int i = 0; i & 10; i++) {offset += sprintf(s + offset, "%d,", rand() % 100);}s[offset - 1] = '\n';//将最后一个逗号换成换行符。printf(s);return 0;}设想当你从数据库中取出一条记录,然后希望把他们的各个字段按照某种规则连接成一个字符串时,就可以使用这种方法,从理论上讲,他应该比不断的strcat 效率高,因为strcat 每次调用都需要先找到最后的那个’’的位置,而在上面给出的例子中,我们每次都利用sprintf 返回值把这个位置直接记下来了。MSDN中例子:// crt_sprintf.c// compile with: /W3// This program uses sprintf to format various// data and place them in the string named buffer.#include &stdio.h&int main( void ){char buffer[200], s[] = "computer", c = 'l';int i = 35,float fp = 1.7320534f; // Format and print various data:j = sprintf( buffer, " String: %s\n", s ); // C4996j += sprintf( buffer + j, " Character: %c\n", c ); // C4996j += sprintf( buffer + j, " Integer: %d\n", i ); // C4996j += sprintf( buffer + j, " Real: %f\n", fp );// C4996// Note: s consider using sprintf_s insteadprintf( "Output:\n%s\ncharacter count = %d\n", buffer, j );}CopyOutput:String: computerCharacter: lInteger: 35Real: 1.732053character count = 79编辑本段使用sprintf 的常见问题sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通常用眼睛再把出错的代码多看几眼就看出来了。sprintf_s()是sprintf()的安全版本,通过指定缓冲区长度来避免sprintf()存在的溢出风险 。在使用VS2008时如果你使用了sprintf函数,那么编译器会发出警告:使用sprintf存在风险,建议使用sprintf_s。这个安全版本的原型是:int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format [,argument] ... );缓冲区溢出第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。忘记了第一个参数低级得不能再低级问题,用printf 用得太惯了。//偶就常犯。:。(变参对应出问题通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤其是对应”*”的那些参数,都提供了吗?不要把一个整数对应一个”%s”,编译器会觉得你欺她太甚了(编译器是obj 和exe 的妈妈,应该是个女的,:P)。strftimesprnitf 还有个不错的表妹:strftime,专门用于格式化时间字符串的,用法跟她表哥很像,也是一大堆格式控制符,只是毕竟小姑娘家心细,她还要调用者指定缓冲区的最大长度,可能是为了在出现问题时可以推卸责任吧。这里举个例子:time_t t = time(0);//产生"YYYY-MM-DD hh:mm:ss"格式的字符串。char s[32];strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));sprintf 在MFC 中也能找到他的知音:CString::Format,strftime 在MFC 中自然也有她的同道:CTime::Format,这一对由于从面向对象哪里得到了赞助,用以写出的代码更觉优雅。
票牛教你如何买到热门、便宜、真实的演出门票!
对新手不错,不过这个我早就会啦.
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或函数应用(5)
本人举得这篇文章写的很详细,很好,其中有些是我自己加进去的。和大家分享一下
sprintf与sscanf用法&
sscanf和sprintf是scanf和printf家族的一对成员,用于处理和分析字符串非常强大得两个函数
头文件 stdio.h
int sscanf(
&&&&&&&&&&&&&const char *buffer,
&&&&&&&&&&&&&const char *format,
&&&&&&&&&&&&&...
&&&&&&&&&&&&&);
int sprintf(
&&&&&&&&&&&&&&&&&&&&char *buffer,
&&&&&&&&&&&&&&const char *format,
&&&&&&&&&&&&&...
&&&&&&&&&&&&&);
功能:类似于scanf和printf 但从字符串*buffer用于输入输出
一、sprintf()
1.sprintf用于格式化字符串
把变量打印到字符串中,从而获得数字的字符形式,这样不需要手工转换。
char c[100];
int k=255;
sprintf(c,&%d&,k);
//c包含&255&
2.sprintf用于进制转换
可以方便地得到变量的十六进制和八进制字符序列,再稍加处理即可得到每一位的值。
char c[100];
int k=255;
sprintf(c,&%x&,k);
//c包含&ff& c[0]='f' c[1]='f'
3.sprintf用于连接字符串
方便地连接两个或者多个字符串
char buf[1024];
char a[100]=&I &;
char b[100]=&love &;
char c[100]=&ACM.&
sprintf(buf,&%s%s%s&,a,b,c);
//buf 包含&I love ACM.&
二、sscanf()
定义函数&&&& int sscanf (const char *str,const char *format,........);
函数说明&&&& sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
返回值&&&& 成功则返回参数数目,失败则返回-1,错误原因存于errno中。
范例&&&& #include&stdio.h&
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\n”,i,j,s);
大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单,特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。
1.&&&&&&&& 常见用法。
charstr[512] = {0};
&&&&&&&& sscanf(&123456 &,&%s&, str);
&&& printf(&str=%s/n&, str);
2.&&&&&&&&取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
&&& sscanf(&123456 &, &%4s&, str);
&&& printf(&str=%s/n&, str);
3.&&&&&&&&取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
&&& sscanf(&123456 abcdedf&, &%[^ ]s&, str);
&&& printf(&str=%s/n&, str);
4. & & & 自动读取
这个函数比较&智能&,貌似认得东西一样,很多时候我们需要寻找字符串中的数字,或是字母用这个函数就可以智能的读取。(当然了用用法7下面的东西也是可以的),比如下面这个程序:
#include&stdio.h&
int main()
& &char s[100]=&(11,ll)&;
& &sscanf(&s[1],&%d&,&v);
& &printf(&%d\n&,v);
& &return 0;
我们的字符串s是(11,ll),最后输出的是11.
5.&&&&&&&&取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
&&& sscanf(&123456abcdedfBCDEF&,&%[1-9,a-z]s&, str);
&&& printf(&str=%s/n&, str);
6.&&&&&&&&取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
&&& sscanf(&123456abcdedfBCDEF&, &%[^A-Z]s&,str);
&&& printf(&str=%s/n&, str);
7 &.sscanf用于处理输入
有些比较麻烦的输入输出用sscanf处理将会非常方便
如hrbeu1002 (这里给出的不是完整代码,其中输出部分只是简单地原样打印出来。)
因为scanf在使用除了%c以外的格式时都忽略换行符'/n',题中用空行来区分不同case的要求
显得难以处理,如果使用sscanf的话,可以先把输入用scanf存入一块缓冲区当中,再用sscanf读取
这样大大减少了工作量。
#include &stdio.h&
int T[100];
int P[100];
bool Input()
char buf[1024];
while(scanf(&%c&,&buf[p])!=EOF)
&&&&&&& if(buf[p]==10)
&&&&&&&&&& if(p==0)return 1;
&&&&&&&&&&sscanf(buf,&%d %d&,&T[i],&P[i]);
&&&&&&&&&& i++;
&&&&&&&&&& p=-1;
&&&&&&& p++;&
void output()
&&&&&&& for(j=0;j&i;j++)
&&&&&&&&&& printf(&%d%d/n&,T[j],P[j]);
&&&&&&& printf(&/n&);
int main()
&&&&&& while(Input())output();
&&&&&& return 0;
sscanf可以支持格式字符%[] 这为分析字符串提供了很大方便(其实scanf也支持%[])&
先看一下%[] 格式:
(1)-: 表示范围,如:%[1-9]表示只读取1-9这几个数字 %[a-z]表示只读取a-z小写字母,类似地 %[A-Z]只读取大写字母
(2)^: 表示不取,如:%[^1]表示读取除'1'以外的所有字符 %[^/]表示除/以外的所有字符
(3),: 范围可以用&,&相连接 如%[1-9,a-z]表示同时取1-9数字和a-z小写字母&
(4)原则:从第一个在指定范围内的数字开始读取,到第一个不在范围内的数字结束%s 可以看成%[] 的一个特例 %[^ ](注意^后面有一个空格!)
这样使用sscanf+%[]可以轻松的分析字符串,很多字符串问题便迎刃而解了。
说明:有第四条原则可以知道其实上面的[]内部的字符也就是停止字符,也就是读到这个字符就会停止,后面的就不会在读了。当然了,对于空格比较特殊,就算没有指定以空格为停止符,读到字符的时候也是会停止的,比如下面的:
#include&stdio.h&
int main()
char str[100];
& &sscanf(&123456 abcdedf&, &%s&, str);
& &printf(&str=%s\n&, str);
& &return 0;
输出是123456,这和%[^ ]的效果是一样的。
以hrbeu3001为例(不是完整代码,没有要求的格式)
只需2个sscanf函数,就能完成题目的要求,代码非常简洁。
#include &stdio.h&
#include &string.h&
intmain(int argc, char *argv[])
&&&& charbuf[1024],str1[100],str2[100],str3[100],str4[100],temp[100]=&&default&&;
&&&& scanf(&%d&,&count);
&&&& while(count--)
&&&&&&& str1[0]='/0';
&&&&&&& str2[0]='/0';
&&&&&&& str3[0]='/0';
&&&&&&& str4[0]='/0';
&&&&&&& scanf(&%s&,buf);
&&&&&&&sscanf(buf,&%[^:]://%[^:,/]:%[,1-9]&,str1,str2,str3,str4);
&&&&&&&sscanf(buf,&%[^:]://%[^:,/]/%[a-z,A-Z,/,~]&,str1,str2,str4);
&&&&&&& if(str3[0]=='/0')strcpy(str3,temp);
&&&&&&& if(str4[0]=='/0')strcpy(str4,temp);
&&&&&&&printf(&%s/n%s/n%s/n%s/n&,str1,str2,str3,str4);
&&&& return 0;
本文来自CSDN博客,转载请标明出处:
sscanf高级用法总结
大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单,特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。
&源代码一如下:
#include &stdio.h&
#include &stdlib.h&
char*tokenstring = &12:34:56-7890&;
char a1[3], a2[3], a3[3];
int i1, i2;
voidmain(void)
&& clrscr();
&& sscanf(tokenstring,& &%2s:%2s:%2s-%2d%2d&,&a1, a2, a3, &i1, &i2);
&& printf(&%s/n%s/n%s/n%d/n%d/n/n&, a1, a2, a3, i1, i2);
&& getch();
源代码二如下:
#include &stdio.h&
#include &stdlib.h&
char*tokenstring = &12:34:56-7890&;
char a1[3], a2[3], a3[3];
int i1, i2;
voidmain(void)
&& clrscr();
&& sscanf(tokenstring,&&%2s%1s%2s%1s%2s%1s%2d%2d&,& a1,& &a, a2, &a3, a3,&a, &i1, &i2);
&& printf(&%s/n%s/n%s/n%d/n%d/n/n&, a1, a2, a3, i1, i2);
&& getch();
源代码三如下:
#include &stdio.h&
#include &stdlib.h&
char*tokenstring = &12:34:56-7890&;
char a1[3], a2[3], a3[3], a4[3], a5[3];
int i1, i2;
voidmain(void)
&&clrscr();
&& sscanf(tokenstring,&&%2s%1s%2s%1s%2s%1s%2s%2s&,& a1,& &a, a2, &a3, a3,&a, a4, a5);
&& i1 =atoi(a4);
&& i2 =atoi(a5);
&&printf(&%s/n%s/n%s/n%d/n%d/n/n&, a1, a2, a3, i1, i2);
&& getch();
方法四如下(以实例说明,原理相同):
/* The following sample illustrates the use of brackets and the
&& caret (^) with sscanf().
&& Compile options needed: none
#include&math.h&
#include &stdio.h&
#include &stdlib.h&
char*tokenstring = &first,25.5,second,15&;
int result,
char o[10], f[10], s[10], t[10];
voidmain()
&& result = sscanf(tokenstring,&%[^','],%[^','],%[^','],%s&, o, s, t, f);
&& fp = atof(s);
&& i& = atoi(f);
&& printf(&%s/n %lf/n %s/n %d/n&, o, fp, t, i);
-------------------------------------------------------------------------------------
sscanf用法几例
devicetype的值,首先原始字符串中是否包含devicetype=,如果包含此串儿则使用如下方式获得devicetype的值。
intmain(int argc, char argv[])
&&&&&& stringszMsg(&_Community=public&_MachineName=192.168.6.96&_Port=161&devicetype=_SnmpWin&seid=2&);
&&&&&&& char *pPos = strstr(szMsg.c_str(),&devicetype=&);
&&&&&&& if(pPos)
&&&&&&&&&&& char*chDevID = new char[strlen(pPos)];
&&&&&&&&&&& if(chDevID)
&&&&&&&&&&& {
&&&&&&&&&&&&&&&memset(chDevID, 0, strlen(pPos));
&&&&&&&&&&&&&&&cout && pPos &&
&&&&&&&&&&&&&&&sscanf(pPos, &devicetype= %[^&]&, chDevID);
&&&&&&&&&&&&&&&cout &&&&&&& &Device Type is:&&& chDevID &&
&&&&&&&&&&&&&&&delete []chDevID;
&&&&&&&&&&& }
例2:请自己比较两段代码运行结果有何不同。
#include&string&
#include &iostream&
intmain(int argc, char * argv[])
&&&&&&& string szMsg(&0001A&);
&&&&&&& unsigned long ulValue = 0;
&&&&&&&sscanf(szMsg.c_str(), &%4x&, &ulValue);
&&&&&&& cout && ulValue &&
&&&&&&& return 0;
#include&string&
#include &iostream&
intmain(int argc, char * argv[])
&&&&&&& string szMsg(&0001A&);
&&&&&&& unsigned long ulValue = 0;
&&&&&&&sscanf(szMsg.c_str(), &%x&, &ulValue);
&&&&&&& cout && ulValue &&
&&&&&&& return 0;
例3:还是让运行结果说话。
#include&string&
#include &iostream&
intmain(int argc, char * argv[])
&&&&&&& string szMsg(&1000ABCD&);
&&&&&&& char szID[32] = {0};
&&&&&&&sscanf(szMsg.c_str(), &%[0-9]&, szID);
&&&&&&& cout && szID &&
&&&&&&& return 0;
--------------------------------------------------------------------------
Readformatted data from a string.
int sscanf(constchar*buffer,constchar*format[,argument&] ...);
Return Value
Eachof these functions returns the number of fields successfully c the return value does not include fields that were read but notassigned. A return value of 0 indicates that no fields were assigned. Thereturn value isEOF&for
an error or if the end of thestring is reached before the first conversion.
Parameters
Storeddata
Format-controlstring
Optionalarguments
Thesscanffunction reads data from&buffer&into the location given by eachargument.Everyargument&must be a pointer to a variable with a type thatcorresponds to a type specifier informat. Theformat&argumentcontrols
the interpretation of the input fields and has the same form andfunction as theformat&argument for thescanf&function.
/*SSCANF.C: This program uses sscanf to read data items
* from a string named tokenstring, then displays them.
#include &stdio.h&
void main( void )
&& char& tokenstring[] = &15 12 14...&;
&& char& s[81];
&& /* Input various data from tokenstring: */
&& sscanf( tokenstring, &%s&, s );
&& sscanf( tokenstring, &%c&, &c );
&& sscanf( tokenstring, &%d&, &i );
&& sscanf( tokenstring, &%f&, &fp );
&& /* Output the data read */
&& printf( &String&&& = %s/n&, s );
&& printf( &Character = %c/n&, c );
&& printf( &Integer:& = %d/n&, i );
&& printf( &Real:&&&& = %f/n&, fp);
String&&& = 15
Character = 1
Integer:& = 15
Real:&&&& = 15.000000
  sscanf() - 从一个字符串中读进与指定格式相符的数据.&
  函数原型:
  Int sscanf( string str, string fmt, mixed var1, mixedvar2 ... );
  int scanf( const char *format [,argument]... );&
  头文件:
  #include&stdio.h&
  说明:
  sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。
  其中的format可以是一个或多个 {%[*][width] [{h | l | I64 | L}]type | ' ' | '/t' | '/n' | 非%符号}
  1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)&
  2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。&
  3、width表示读取宽度。&
  4、{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
  5、type :这就很多了,就是%s,%d之类。&
  6、特别的:%*[width] [{h | l | I64| L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值
  支持集合操作:
  %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
  %[aB'] 匹配a、B、'中一员,贪婪性
  %[^a] 匹配非a的任意字符,贪婪性
  1. 常见用法。
  char buf[512] = ;
  sscanf(&123456 &, &%s&, buf);
  printf(&%s/n&, buf);
  结果为:123456
  2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
  sscanf(&123456 &, &%4s&, buf);
  printf(&%s/n&, buf);
  结果为:1234&
  3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
  sscanf(&123456 abcdedf&, &%[^ ]&,buf);
  printf(&%s/n&, buf);
  结果为:123456&
  4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
  sscanf(&123456abcdedfBCDEF&,&%[1-9a-z]&, buf);
  printf(&%s/n&, buf);
  结果为:123456abcdedf&
  5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
  sscanf(&123456abcdedfBCDEF&,&%[^A-Z]&, buf);
  printf(&%s/n&, buf);
  结果为:123456abcdedf&
  6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将&iios/&过滤掉,再将非'@'的一串内容送到buf中
  sscanf(&iios/12DDWDFF@122&,&%*[^/]/%[^@]&, buf);
  printf(&%s/n&, buf);
  结果为:12DDWDFF&
  7、给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
  sscanf(“hello, world”, &%*s%s&, buf);&
  printf(&%s/n&, buf);&
  结果为:world
  %*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
  如果没有空格则结果为NULL。
  sscanf的功能很类似于正则表达式, 但却没有正则表达式强大,所以如果对于比较复杂的字符串处理,建议使用正则表达式.
  //-------------------------------------------------------
  sscanf,表示从字符串中格式化输入&
  上面表示从str中,输入数字给x,就是32700&
  久以前,我以为c没有自己的split string函数,后来我发现了sscanf;一直以来,我以为sscanf只能以空格来界定字符串,现在我发现我错了。&
  sscanf是一个运行时函数,原形很简单:&
  int sscanf(&
  const char *buffer,&
  const char *format [,&
  argument ] ...&
  它强大的功能体现在对format的支持上。&
  我以前用它来分隔类似这样的字符串:&
  int a, b,&
  sscanf(&&, &%d:%d:%d&,a, b, c);&
  以及 - :&
  char sztime1[16] = &&, sztime2[16] =&&;&
  sscanf(& - &, &%s- %s&, sztime1, sztime2);&
  但是后来,我需要处理-&
  仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。&
  我需要重新设计一个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统一的风格,我需要改动很多地方,把已有的sscanf替换成我自己的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满而入睡;一觉醒来,发现其实不必。
  format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。&
  %[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。&
  所以那个问题也就迎刃而解了:&
  sscanf(& - &,&%[0-9,:] - %[0-9,:]&, sztime1, sztime2);&
  在softmse (Jake) 的问题贴http://community.csdn.net/Expert/topic/.xml?temp=.4321558中 ,周星星给出了一个很cool的sscanf用例,而后通过学习,发现sscanf真棒,现做一总结。
  原问题:&
  iios/12DDWDFF@122&
  获取/和@之间的字符串怎么做&
  C程序里面有什么函数吗?&
  周星星的代码:&
  #include &stdio.h&&
  int main()&
  const char* s = &iios/12DDWDFF@122&;&
  char buf[20];&
  sscanf( s, &%*[^/]/%[^@]&, buf );&
  printf( &%s/n&, buf );&
  return 0;&
  结果为:12DDWDFF&
  sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。&
  函数原型:&
  int scanf( const char *format [,argument]... );&
  其中的format可以是一个或多个 {%[*][width] [{h | l | I64 | L}]type | ' ' | '/t' | '/n' | 非%符号},
  注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。&
  width:宽度,一般可以忽略,用法如:&
  const char sourceStr[] = &hello, world&;&
  char buf[10] = ;&
  sscanf(sourceStr, &%5s&, buf); //%5s,只取5个字符&
  cout && buf&&&
  结果为:hello&
  {h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
  type :这就很多了,就是%s,%d之类。&
  特别的:&
  %*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值。如:&
  const char sourceStr[] = &hello, world&;&
  char buf[10] = ;&
  sscanf(sourceStr, &%*s%s&, buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了&
  cout && buf&&&
  结果为:world&
  支持集合操作:&
  %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)&
  %[aB'] 匹配a、B、'中一员,贪婪性&
  %[^a] 匹配非a的任意字符,贪婪性&
  是不是感觉眼熟了啊,不错,这和正则表达式很相似,而且仍然支持过滤,即可以有%*[a-z].如:&
  星星大哥例子回顾:&
  const char* s = &iios/12DDWDFF@122&;&
  char buf[20];&
  sscanf( s, &%*[^/]/%[^@]&, buf );&
  printf( &%s/n&, buf );&
  由例子3-》取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
  sscanf(&123456 abcdedf&, &%[^ ]&,buf);
  printf(&%s/n&, buf);
  结果为:123456&
  所以周星星的代码总结应该为:
  const char* s = &iios/12DDWDFF@122&;
  char buf[20];
  sscanf( s, &%*[^/]/%[^@]&, buf );
  printf( &%s/n&, buf );
  先将 &iios/&过滤掉,再将到字符'@'为止的一串12DDWDFF(由例3可得此串到@为止,把@122舍掉)内容即是:12DDWDFF送到buf中,得到结果。
  PS: 向星星大哥和softmse (Jake) 致谢了,有了你们才有它啊
这里有些sscanf()的一些使用说明,都是从论坛,Blog里整理出来的。供大家使用。&
&& 通过学习和使用个人认为,在字符串格式不是很复杂,但是也并不简单的时候用这个函数比较合适,这个尺度就要靠自己把握了,字符串不是很复杂,但自己写个处理的函数比较麻烦,效率也不高,就用这个函数,如果字符串很复杂,那就用正则表达式吧。
不多说了,看看下面这些介绍和列子吧!
名称:sscanf() - 从一个字符串中读进与指定格式相符的数据.&
函数原型:&
Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );&
int scanf( const char *format [,argument]... );
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。&
其中的format可以是一个或多个 {%[*] [width][{h | l | I64 | L}]type | ' ' | '/t' | '/n' | 非%符号}
支持集合操作:&
&&&& %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)&
&&&& %[aB'] 匹配a、B、'中一员,贪婪性&
&&&& %[^a] 匹配非a的任意字符,贪婪性
1. 常见用法。&
&&& char buf[512] = {0};&
&&& sscanf(&123456 &, &%s&, buf);&
&&& printf(&%s/n&, buf);&
结果为:123456
2.取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。&
&&& sscanf(&123456 &, &%4s&, buf);&
&&& printf(&%s/n&, buf);&
结果为:1234
3.取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。&
&&& sscanf(&123456 abcdedf&, &%[^ ]&, buf);&
&&& printf(&%s/n&, buf);&
结果为:123456&
4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。&
&&& sscanf(&123456abcdedfBCDEF&,&%[1-9a-z]&, buf);&
&&& printf(&%s/n&, buf);&
结果为:123456abcdedf&
5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。&
&&& sscanf(&123456abcdedfBCDEF&, &%[^A-Z]&,buf);&
&&& printf(&%s/n&, buf);&
结果为:123456abcdedf
6、给定一个字符串,获取 / 和 @ 之间的字符串,先将&iios/&过滤掉,再将非的一串内容送到buf中
&&& sscanf(&&,&%*[^/]/%[^@]&, buf);
&&& printf(&%s/n&, buf);&
结果为:12DDWDFF&
7、给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)
&&&sscanf(“hello, world”, &%*s%s&,buf);&&&
&&& printf(&%s/n&, buf);&
结果为:world&
%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了&
如果没有空格则结果为NULL。&
char *s=&1try234delete5&&
sscanf(s, &1%[^2]234%[^5]&, s1, s2);&
scanf的format中出现的非转换字符(%之前或转换字符之后的字符),即此例中的1234用来跳过输入中的相应字符;&
‘[]’的含义与正则表达式中相同,表示匹配其中出现的字符序列;^表示相反。使用[ ]时接收输入的变量必须是有足够存储空间的char、signed char、unsigned char数组。记住[也是转换字符,所以没有s了。
8、分割以某字符标记的字符串。
chartest[]=&222,333,444,,,555,666&;&
char s1[4],s2[4],s3[4],s4[4],s5[4],s6[4],s7[4];&
sscanf(test,&%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]&,s1,s2,s3,s4,s5,s6,s7);
printf(&sssa1=%s&,s1);&
printf(&sssa2=%s&,s2);&
printf(&sssa3=%s&,s3);&
printf(&sssa4=%s&,s4);&
printf(&sssa5=%s&,s5);&
printf(&sssa6=%s&,s6);&
printf(&sssa7=%s&,s7);&
9、一个提取用户个人资料中邮件地址的例子&
#include&cstdlib&&
#include&cstdio&&
int main()&
&&& char a[20]={0};&
&&& char b[20]={0};&
&&& //假设email地址信息以';'结束&
&&&sscanf(&email:;&,&%*[^:]:%[^;]&,a);&
&&& //假设email地址信息没有特定的结束标志&
&&& sscanf(&email:&,&%*[^:]:%s&,b);
&&& printf(&%s/n&,a);&
&&& printf(&%s/n&,b);&
&&& system(&pause&);&
&&& return 0;&
关键是&%*[^:]:%[^;]&和&%*[^:]:%s&这两个参数的问题&
%*[^:]&&& 表示满足&[]&里的条件将被过滤掉,不会向目标参数中写入值。这里的意思是在&
&&&&&&&&&&& 第一个':'之前的字符会在写入时过滤掉,'^'是表示否定的意思,整个参数翻译&
&&&&&&&&&&& 成白话就是:将在遇到第一个':'之前的(不为':'的)字符全部过滤掉。&
:&&&&&&&& 自然就是跳过':'的意思。&
%[^;]&&&& 拷贝字符直到遇到';'。
一下摘自:
%[ ] 的用法:%[ ]表示要读入一个字符集合, 如果[ 后面第一个字符是”^”,则表示反意思。
&&&&&&&&&&&&&&&&&&&&[ ]内的字符串可以是1或更多字符组成。空字符集(%[])是违反规定的,可
&&&&&&&&&&&&&&&&&&&&导致不可预知的结果。%[^]也是违反规定的。&
%[a-z]读取在 a-z 之间的字符串,如果不在此之前则停止,如
&&&&&&&&&&&&&char s[]=&hello, my friend”;&&&&&&&& // 注意:,逗号在不 a-z之间
&&&&&&&&&&&&&sscanf( s, “%[a-z]”, string ) ; // string=hello
%[^a-z] 读取不在 a-z 之间的字符串,如果碰到a-z之间的字符则停止,如
&&&&&&&&&&&&&char s[]=&HELLOkitty” ;&&&&&&&& // 注意: ,逗号在不 a-z之间
&&&&&&&&&&&&&sscanf( s, “%[^a-z]”, string ) ; // string=HELLO
%*[^=]&&& 前面带 * 号表示不保存变量。跳过符合条件的字符串。
&&&&&&&&&&&&&char s[]=&notepad=1.0.0.1001& ;
&&&&&&char szfilename [32] = && ;
&&&&&&int i = sscanf( s, &%*[^=]&, szfilename ) ; // szfilename=NULL,因为没保存
inti = sscanf( s, &%*[^=]=%s&, szfilename ) ; // szfilename=1.0.0.1001
%40c&&&&&读取40个字符
&&&&&&The run-time
librarydoes not automatically append a null terminator
tothe string, nor does reading 40 characters
automaticallyterminate the scanf() function. Because the
libraryuses buffered input, you must press the ENTER key
toterminate the string scan. If you press the ENTER before
thescanf() reads 40 characters, it is displayed normally,
andthe library continues to prompt for additional input
untilit reads 40 characters
%[^=]&&&& 读取字符串直到碰到’=’号,’^’后面可以带更多字符,如:
&&&&&&&&&&&&&char s[]=&notepad=1.0.0.1001& ;
&&&&&&char szfilename [32] = && ;
&&&&&&int i = sscanf( s, &%[^=]&, szfilename ) ; //szfilename=notepad&&&&&
&&&&&&如果参数格式是:%[^=:] ,那么也可以从 notepad:1.0.0.1001读取notepad
&&&&&&&&&&&&&
使用例子:
chars[]=&notepad=1.0.0.1001& ;
charszname [32] = && ;
charszver [32] = “” ;
sscanf(s, &%[^=]=%s&, szname , szver ) ; // szname=notepad, szver=1.0.0.1001
总结:%[]有很大的功能,但是并不是很常用到,主要因为:
1、许多系统的 scanf 函数都有漏洞. (典型的就是 TC 在输入浮点型时有时会出错).
2、用法复杂,容易出错.
3、编译器作语法分析时会很困难, 从而影响目标代码的质量和执行效率.
个人觉得第3点最致命,越复杂的功能往往执行效率越低下。而一些简单的字符串分析我们可以自已处理。
转载时请注明出处和作者联系方式
文章出处:
大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单,特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。
1. 常见用法。
& &&char&str[512]={0};
& & sscanf(&123456 &,&%s&,&str);
& &&printf(&str=%s/n&,&str);
2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
& & sscanf(&123456 &,&%4s&,str);
& &&printf(&str=%s/n&,&str);
3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
& & sscanf(&123456 abcdedf&,&%[^ ]&,str);
& &&printf(&str=%s/n&,&str);
4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
& & sscanf(&123456abcdedfBCDEF&,&%[1-9a-z]&,str);
& &&printf(&str=%s/n&,&str);
5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
& & sscanf(&123456abcdedfBCDEF&,&%[^A-Z]&,str);
& &&printf(&str=%s/n&,&str);
另附说明:
“%[ ]”符号用于声明字符串,它比“%s”更具体,可以用于设置读取的样式。例如“%[a-z]”只读取小
写字母,读到其它字符就结束。注意,方括号中如果有“^”,代表一直读到某字符为止。例如:
“%[^#]”:读取字符串,一直到出现“#”号为止。
“%20[^#]”:读取20个字节的字符串,出现“#”号时结束。
sscanf函数用法总结
很久以前,我以为c没有自己的split string函数,后来我发现了sscanf;一直以来,我以为sscanf只能以空格来界定字符串,现在我发现我错了。
sscanf是一个运行时函数,原形很简单:
int sscanf(
const char *buffer,
const char *format [,
argument ] ...
它强大的功能体现在对format的支持上。
我以前用它来分隔类似这样的字符串:
sscanf(&&, &%d:%d:%d&, a, b, c);
char sztime1[16] = &&, sztime2[16] = &&;
sscanf(& - &, &%s - %s&, sztime1,sztime2);
但是后来,我需要处理-
仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。
我需要重新设计一个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统一的风格,我需要改动很多地方,把已有的sscanf替换成我自己的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满而入睡;一觉醒来,发现其实不必。
format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。
%[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。
所以那个问题也就迎刃而解了:
sscanf(& - &, &%[0-9,:] - %[0-9,:]&,sztime1, sztime2);
在softmse (Jake) 的问题贴http://community.csdn.net/Expert/topic/.xml?temp=.4321558中 ,周星星给出了一个很cool的sscanf用例,而后通过学习,发现sscanf真棒,现做一总结。
iios/12DDWDFF@122
获取/和@之间的字符串怎么做
C程序里面有什么函数吗?
周星星的代码:
const char* s = &iios/12DDWDFF@122&;
char buf[20];
sscanf(s, &%*[^/]/%[^@]&, buf );
printf( &%s/n&, buf );
结果为:12DDWDFF
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
函数原型:
intscanf( const char *format [,argument]... );
其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 |L}]type | ' ' | '/t' | '/n' | 非%符号},
注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
width:宽度,一般可以忽略,用法如:
constchar sourceStr[] = &hello, world&;
charbuf[10] = {0};
sscanf(sourceStr,&%5s&, buf); //%5s,只取5个字符
cout&& buf&& 结果为:hello {h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。 type :这就很多了,就是%s,%d之类。 特别的: %*[width] [{h | l | I64 |L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值。如: const charsourceStr[] = &hello, world&; char buf[10]
= {0}; sscanf(sourceStr,&%*s%s&, buf); //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了 cout && buf&& 结果为:world 支持集合操作: %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配) %[aB'] 匹配a、B、'中一员,贪婪性 %[^a] 匹配非a的任意字符,贪婪性是不是感觉眼熟了啊,不错,这和正则表达式很相似,而且仍然支持过滤,即可以有%*[a-z].如: 星星大哥例子回顾: const char* s =
&iios/12DDWDFF@122&; char buf[20];sscanf( s, &%*[^/]/%[^@]&, buf ); printf( &%s/n&, buf ); 先将 &iios/&过滤掉,再将非'@'的一串内容送到buf中,cool.得到结果。 PS: 向星星大哥和softmse (Jake) 致谢了,有了你们才有它啊 大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。它的使用方法简单,特别对于整数和浮点数来说。但新手可能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。
1. 常见用法。 char str[512] = {0};sscanf(&123456 &, &%s&, str); printf(&str=%s/n&,str); 2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。 sscanf(&123456 &, &%4s&, str);printf(&str=%s/n&, str); 3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。 sscanf(&123456 abcdedf&, &%[^ ]&, str);printf(&str=%s/n&,
str); 4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。sscanf(&123456abcdedfBCDEF&, &%[1-9a-z]&, str);printf(&str=%s/n&, str); 5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。 sscanf(&123456abcdedfBCDEF&, &%[^A-Z]&, str);printf(&str=%s/n&, str); 源代码一如下: #include
char*tokenstring = &12:34:56-7890&;
char a1[3], a2[3], a3[3];
int i1, i2;
voidmain(void)
sscanf(tokenstring, &%2s:%2s:%2s-%2d%2d&, a1, a2, a3, &i1, &i2);
printf(&%s/n%s/n%s/n%d/n%d/n/n&, a1, a2, a3, i1, i2);
源代码二如下:
char*tokenstring = &12:34:56-7890&;
char a1[3], a2[3], a3[3];
int i1, i2;
voidmain(void)
sscanf(tokenstring, &%2s%1s%2s%1s%2s%1s%2d%2d&, a1, &a, a2,&a3, a3, &a, &i1, &i2);
printf(&%s/n%s/n%s/n%d/n%d/n/n&, a1, a2, a3, i1, i2);
源代码三如下:
char*tokenstring = &12:34:56-7890&;
char a1[3], a2[3], a3[3], a4[3], a5[3];
int i1, i2;
voidmain(void)
sscanf(tokenstring, &%2s%1s%2s%1s%2s%1s%2s%2s&, a1, &a, a2,&a3, a3, &a, a4, a5);
i1 =atoi(a4);
i2 =atoi(a5);
printf(&%s/n%s/n%s/n%d/n%d/n/n&,a1, a2, a3, i1, i2);
方法四如下(以实例说明,原理相同):
/* The following sample illustrates the use of brackets and the
caret (^) with sscanf().
Compile options needed: none
char*tokenstring = &first,25.5,second,15&;
int result,
char o[10], f[10], s[10], t[10];
voidmain()
result = sscanf(tokenstring, &%[^','],%[^','],%[^','],%s&, o, s, t,f);
fp = atof(s);
i = atoi(f);
printf(&%s/n %lf/n %s/n %d/n&, o, fp, t, i);
scanf(格式化字符串输入)
scanf,fscanf
#include&stdio.h&
int sscanf (const char *str,const char * format,........);
sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
返回值
成功则返回参数数目,失败则返回-1,错误原因存于errno中。
#include&stdio.h&
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/n”,i,j,s);
10 27 aaaaa
我以前用它来分隔类似这样的字符串:
sscanf(&&,&%d:%d:%d&, a, b, c);
char sztime1[16] = &&,sztime2[16] = &&;
sscanf(& -&, &%s - %s&, sztime1, sztime2);
但是后来,我需要处理-
仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。
我需要重新设计一个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统一的风格,我需要改动很多地方,把已有的sscanf替换成我自己的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满而入睡;一觉醒来,发现其实不必。
format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。
%[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。
获取/和@之间的字符串怎么做
C程序里面有什么函数吗?
周星星的代码:
#include&stdio.h&
&&& const char* s = &&;
&&& char buf[20];
&&&sscanf( s, &%*[^/]/%[^@]&, buf );
&&& printf( &%s/n&, buf );
&&&return 0;
结果为:12DDWDFF
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
函数原型:
intscanf( const char *format [,argument]... );
其中的format可以是一个或多个 {%[*] [width] [{h | l | I64 |L}]type& |& ' ' |& '/t' | '/n' | 非%符号},
注:{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
&width:宽度,一般可以忽略,用法如:
const&char sourceStr[] = &hello, world&;
charbuf[10] = {0};
sscanf(sourceStr,&%5s&, buf);&& //%5s,只取5个字符
cout&& buf&&
结果为:hello
{h| l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。
type:这就很多了,就是%s,%d之类。
%*[width][{h | l | I64 | L}]type& 表示满足该条件的被过滤掉,不会向目标参数中写入值。如:
const&char sourceStr[] = &hello, world&;
charbuf[10] = {0};
sscanf(sourceStr,&%*s%s&, buf);&& //%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
cout&& buf&&
结果为:world
支持集合操作:
&&&&&&&&%[a-z]& 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
&&&&&&& %[aB']& 匹配a、B、'中一员,贪婪性
&&&&&&&&%[^a]&&& 匹配非a的任意字符,贪婪性
&&&&&&&&是不是感觉眼熟了啊,不错,这和正则表达式很相似,而且仍然支持过滤,即可以有%*[a-z].如:
星星大哥例子回顾:
&&&const char* s = &&;
&&& char buf[20];
&&&sscanf( s, &%*[^/]/%[^@]&, buf );
&&& printf( &%s/n&, buf );
先将 &iios/&过滤掉,再将非的一串内容送到buf中,cool.得到结果。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:74167次
积分:1873
积分:1873
排名:第16321名
原创:110篇
转载:44篇
(2)(2)(2)(2)(1)(5)(5)(20)(9)(1)(5)(12)(11)(9)(15)(3)(16)(7)(6)(8)(13)

我要回帖

更多关于 sprintf的用法 的文章

 

随机推荐