c语言编程,关于sscanf通过中文逗号截取字符串的问题
发布时间:2025-05-21 11:04:03 发布人:远客网络
一、c语言编程,关于sscanf通过中文逗号截取字符串的问题
在处理字符串的程序当中,经常会分析字符串,从一大长串的字符串截取我们需要的数据,这如果通过自己手写函数来分析,虽然可以,但当你知道sscanf的功能,那就自己写函数分析就显得多此一举。
这些函数的使用都很简单,总结一下,等下次使用一目了然。俗话说:好记性不如烂笔头,记录下来就是效率。
以下源代码是本人测试的源文件,附带讲解注释。
1./*****************************************************
6.** Description: sscanf function
7.******************************************************/
12.static void sscanf_test(void);
14.static void sscanf_test(void)
25. string="china beijing 123";
26. ret= sscanf(string,"%s%s%d", buf1, buf2,&digit);
27. printf("1.string=%s\n", string);
28. printf("1.ret=%d, buf1=%s, buf2=%s, digit=%d\n\n", ret, buf1, buf2, digit);
31.**1.ret=2, buf1=china, buf2=beijing, digit=123
32.**可以看出,sscanf的返回值是读取的参数个数
37. sscanf(string,"%5s", buf1);
38. printf("2.string=%s\n", string);
39. printf("2.buf1=%s\n\n", buf1);
45./*3.取到指定字符为止的字符串*/
47. sscanf(string,"%[^/]", buf1);
48. printf("3.string=%s\n", string);
49. printf("3.buf1=%s\n\n", buf1);
55./*4.取到指定字符集为止的字符串*/
57. sscanf(string,"%[^A-Z]", buf1);
58. printf("4.string=%s\n", string);
59. printf("4.buf1=%s\n\n", buf1);
65./*5.取仅包含指定字符集的字符串*/
67. sscanf(string,"%[0-9]%[a-z]%[A-Z]", buf1, buf2, buf3);
68. printf("5.string=%s\n", string);
69. printf("5.buf1=%s, buf2=%s, buf3=%s\n\n", buf1, buf2, buf3);
75./*6.获取指定字符中间的字符串*/
76. string="ios<Android>wp7";
77. sscanf(string,"%*[^<]<%[^>]", buf1);
78. printf("6.string=%s\n", string);
79. printf("6.buf1=%s\n\n", buf1);
87. sscanf(string,"%[a-z]VS%[a-z]", buf1, buf2);
88. printf("7.string=%s\n", string);
89. printf("7.buf1=%s, buf2=%s\n\n", buf1, buf2);
95./*8.分割以某字符隔开的字符串*/
96. string="android-iphone-wp7";
98.**字符串取道'-'为止,后面还需要跟着分隔符'-',
99.**起到过滤作用,有点类似于第7点
101. sscanf(string,"%[^-]-%[^-]-%[^-]", buf1, buf2, buf3);
102. printf("8.string=%s\n", string);
103. printf("8.buf1=%s, buf2=%s, buf3=%s\n\n", buf1, buf2, buf3);
106.**8.buf1=android, buf2=iphone, buf3=wp7
110. string="Email:beijing@sina.com.cn";
111. sscanf(string,"%[^:]:%[^@]@%[^.].%s", buf1, buf2, buf3, buf4);
112. printf("9.string=%s\n", string);
113. printf("9.buf1=%s, buf2=%s, buf3=%s, buf4=%s\n\n", buf1, buf2, buf3, buf4);
116.**9.buf1=Email, buf2=beijing, buf3=sina, buf4=com.cn
120.int main(int argc, char**argv)
130.**Linux Ubuntu 2.6.32-24-generic-pae#39-Ubuntu SMP Wed Jul 28 07:39:26 UTC 2010 i686 GNU/Linux
131.**gcc version 4.4.3(Ubuntu 4.4.3-4ubuntu5)
133.gzshun@ubuntu:~/c/sscanf$ gcc sscanf.c-o sscanf
134.gzshun@ubuntu:~/c/sscanf$./sscanf
135.1.string=china beijing 123
136.1.ret=3, buf1=china, buf2=beijing, digit=123
148.5.buf1=0123, buf2=abc, buf3=ABC
150.6.string=ios<android>wp7
156.8.string=android-iphone-wp7
157.8.buf1=android, buf2=iphone, buf3=wp7
159.9.string=Email:beijing@sina.com.cn
160.9.buf1=Email, buf2=beijing, buf3=sina, buf4=com.cn
本篇文章来源于 Linux公社网站(www.linuxidc.com)原文链接:
二、sscanf()什么意思
sscanf,表示从字符串中格式化输入
上面表示从str中,输入数字给x,就是32700
久以前,我以为c没有自己的split string函数,后来我发现了sscanf;一直以来,我以为sscanf只能以空格来界定字符串,现在我发现我错了。
sscanf是一个运行时函数,原形很简单:
它强大的功能体现在对format的支持上。
我以前用它来分隔类似这样的字符串2006:03:18:
sscanf("2006:03:18","%d:%d:%d", a, b, c);
char sztime1[16]="", sztime2[16]="";
sscanf("2006:03:18- 2006:04:18","%s-%s", sztime1, sztime2);
但是后来,我需要处理2006:03:18-2006:04:18
仅仅是取消了‘-’两边的空格,却打破了%s对字符串的界定。
我需要重新设计一个函数来处理这样的情况?这并不复杂,但是,为了使所有的代码都有统一的风格,我需要改动很多地方,把已有的sscanf替换成我自己的分割函数。我以为我肯定需要这样做,并伴随着对sscanf的强烈不满而入睡;一觉醒来,发现其实不必。
format-type中有%[]这样的type field。如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。
%[]类似于一个正则表达式。[a-z]表示读取a-z的所有字符,[^a-z]表示读取除a-z以外的所有字符。
sscanf("2006:03:18- 2006:04:18","%[0-9,:]-%[0-9,:]", sztime1, sztime2);
在softmse(Jake)的问题贴中,周星星给出了一个很cool的sscanf用例,而后通过学习,发现sscanf真棒,现做一总结。
const char* s="iios/12DDWDFF@122";
sscanf( s,"%*[^/]/%[^@]", buf);
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";
sscanf(sourceStr,"%5s", buf);//%5s,只取5个字符
cout<< buf<< endl;
{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";
sscanf(sourceStr,"%*s%s", buf);//%*s表示第一个匹配到的%s被过滤掉,即hello被过滤了
cout<< buf<< endl;
%[a-z]表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB']匹配a、B、'中一员,贪婪性
%[^a]匹配非a的任意字符,贪婪性
是不是感觉眼熟了啊,不错,这和正则表达式很相似,而且仍然支持过滤,即可以有%*[a-z].如:
const char* s="iios/12DDWDFF@122";
sscanf( s,"%*[^/]/%[^@]", buf);
先将"iios/"过滤掉,再将非'@'的一串内容送到buf中,cool.得到结果。
PS:向星星大哥和softmse(Jake)致谢了,有了你们才有它啊