【ACM非算法部分】scanf()函数
scanf函数
格式说明符:
%c 字符型
%d 十进制数
%i 读入十进制,八进制,十六进制数。输入的时候正常是十进制数,若输入0前缀的数将读入八进制,0x前缀读入16进制。若输入09 则读入0,9进入缓冲区
%f 浮点数
%o 八进制数
%s 字符串,碰到空格或回车结束
%x 16进制数
%p 指针
%n 至此已读入值的等价字符数
1 #include <stdio.h> 2 #include <stdlib.h> 3 int main() 4 { 5 int a,x; 6 char s[100]; 7 while(1) 8 { 9 fflush(stdin); 10 scanf("%d%n",&a,&x); 11 printf("%d %d\n",a,x); 12 } 13 return 0; 14 }
这个程序输入123会输出123 3。要注意的是,若没有fflush(stdin);第一次输入123的时候会输出123 3,第二次则会输出123 4。因为上次键入的回车也计算在内了。如果输入123之前多敲几次回车,则x的值要多相应的次数。因此,%u读入的是当前已读入的等价字符数。若将%n放在格式字符串的开头,则读入的数字为0。
%u 无符号十进制数
[] 扫描字符集合,这个在后面说明。
%% 读入’%’字符
附加格式说明:
l 长度修饰符,输入“长”数据
h 长度修饰符,输入“短”数据
整型常数 输入数据所占宽度。
如:
scanf(“%4d”,&a);
输入123456时,a的值为1234,56被加入缓冲区用于下次读入。
* 表示输入项不赋给变量。如:
scanf(“%d%*d%d”,&a,&b);
输入1 2 3 时,a为1,b为3,2被跳过不赋给任何变量。
[]:
1
%[ABC]
使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。
用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。
对于许多实现来说,用连字符可以说明一个范围。 例如,以下扫描集使 scanf() 接受字母 A 到 Z:%[A-Z]
重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。
%[^A]读入字符串以A结尾。如输入SDFASDF则读入的字符串为SDF。要注意的是,读入的时候只以A为结尾,空格和回车都不能结束输入。
要用scanf实现gets的功能,只需要这样写:scanf("%[^\n]",s);就可以了。
更多详情可以参见百度百科:
进阶:
函数:sscanf()
函数原型:
int sscanf( const char *, const char *, ...);
int sscanf(const char *buffer,const char *format,[argument ]...);
buffer存储的数据
format格式控制字符串
argument 选择性设定字符串
sscanf会从buffer里读进数据,依照format的格式将数据写入到argument里。
sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。
1. 常见用法。
char buf[512] ;
sscanf("123456 ", "%s", buf);//此处buf是数组名,它的意思是将123456以%s的形式存入buf中!
printf("%s\n", buf);
结果为:123456
效果和strcpy(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
当输入: sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf);
printf("%s\n",buf);
结果为:123456
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。
(注意:“,”之后有一空格,%s遇空格停止,加*则是忽略第一个读到的字符串)
sscanf(“hello, world”, "%*s%s", buf);
printf("%s\n", buf);
结果为:world
%*s表示第一个匹配到的%s被过滤掉,即“hello,”被过滤了
如果没有空格则结果为NULL。
ACM使用案例:
HDU1106 排序
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1106
解题代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 int cmp(int *a,int *b) 4 { 5 return *a-*b; 6 } 7 int main() 8 { 9 char s[1005],*p,a[20]; 10 int b,x[1000],k,i; 11 while(gets(s)) 12 { 13 p=s; 14 k=0; 15 do 16 { 17 sscanf(p,"%[^5]",a); 18 if(*p!=0&&*p!='5') 19 if(sscanf(a,"%d",&b)==1) 20 { 21 x[k]=b; 22 k++; 23 } 24 while(*p!='5'&&*p!=0) p++; 25 p++; 26 }while(*(p-1)!=0); 27 qsort(x,k,sizeof(int),cmp); 28 for(i=0;i<k;i++) 29 { 30 if(i!=0) printf(" "); 31 printf("%d",x[i]); 32 } 33 printf("\n"); 34 } 35 return 0; 36 }