ANSI C (2) —— str系列函数
来源:互联网 发布:javascript效果大全 编辑:程序博客网 时间:2024/06/06 08:57
参数可变的函数
#include <stdio.h>#include <stdarg.h>int mymax(int count, ...){ int maxm=-1; va_list address; int i,number; va_start(address,count); /* 设置 address为第一个参数的地址 */ for(i=0;i<count;i++){ number=va_arg(address,int); /* 得到该地址的数字,且下移指针 */ maxm=maxm>number?maxm:number; } return maxm;}int main(){ int a[5]; int sum; puts("enter some numbers, the numbers is not more than 5"); while(~scanf("%d",&sum) && sum){ for(int i=0;i<sum;i++) scanf("%d",&a[i]); switch (sum){ case 1: printf("%d\n",mymax(sum,a[0])); break; case 2: printf("%d\n",mymax(sum,a[0],a[1])); break; case 3: printf("%d\n",mymax(sum,a[0],a[1],a[2])); break; case 4: printf("%d\n",mymax(sum,a[0],a[1],a[2],a[3])); break; case 5: printf("%d\n",mymax(sum,a[0],a[1],a[2],a[3],a[4])); break; } } return 0;}
strncat
strncat(string1,string2,n):
将字符串1和2连接在一起,不过可以指定字符串2中追加到1的长度。如果n大于等于string2的长度,那么效果和strcat等价,如果小于长度值,那么我们可以连接一部分。
比如:
#include <stdio.h>#include <string.h>int main(){ char s1[5]="1234"; char s2[10]="abcdefghi"; strncat(s1,s2,19); printf("%s\n", s1); return 0;}/*for strncat(s1,s2,19) :1234abcdefghifor strncat(s1,s2,4) :1234abcd*/
strncpy
char *strncpy(char *dest, const char *src, size_t n);
strncpy()会将参数src字符串拷贝前n个字符至参数dest所指的地址。
如果src的字符个数小于n就用空格填充。
下面是它和strcpy()的对比:
int main(){ char s1[]="I love Beijing."; char s2[]="I'm Chinese."; strncpy(s1,s2,8); printf("%s\n", s1); strcpy(s1,s2); printf("%s\n", s1); return 0;}/*I'm Chineijing.I'm Chinese.*/
strncmp
关于两个字符串的比较:
1)他们字符串长度不相等,但是相应的字符都是一样的。 长的字符串>短的字符串
2)存在相同位置字符不等的情况。字符大的优先级高
和strcmp()对应的函数strncmp(),它可以指定字符串比较的长度。
例如:
char s1[8]="abcdef"; char s2[8]="abcjhg"; printf("%d\n",strncmp(s1,s2,0)); printf("%d\n",strncmp(s1,s2,3)); printf("%d\n",strncmp(s1,s2,4));/*00-6*/
现在思考一个问题:
假设第三个参数是负数,那么结果会是怎样的呢?
我改变参数后:
printf(“%d\n”,strncmp(s1,s2,-1));
结果输出了
-6
这个结果让我有点不解
我查看了gun libc中的函数源码:
int STRNCMP (const char *s1, const char *s2, size_t n){ unsigned char c1 = '\0'; unsigned char c2 = '\0'; if (n >= 4) { size_t n4 = n >> 2; do { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; } while (--n4 > 0); n &= 3; } while (n > 0) { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; n--; } return c1 - c2;}
按常理讲应该返回0才对,这究竟是为什么?
( strstr ) ( strchr ) ( strrchr )
strstr 查找字符串中子串出现的位置
strchr 查找字符首次出现的位置
strrchr 查找字符最后出现的位置
以下是使用例子:
int main(){ printf("strstr: %s\n",strstr("I love Beijing.","Bei")); printf("strchr: %s\n",strchr("I love Beijing.",'i')); printf("strchr: %s\n",strrchr("I love Beijing.",'i')); printf("strstr: %s\n",strstr("I love Beijing.","???")); return 0;}/*strstr: Beijing.strchr: ijing.strchr: ing.strstr: (null)*/
编写cat函数的栈溢出经历
#include <stdio.h>#include <string.h>char *cat(char *s1,char *s2){ char *p=s1; while(s1[0]!=0) s1++; while(s2[0]!=0){ s1[0]=s2[0]; // 链表和数组完全是两码事,这里必须全部复制。 s1++; s2++; } s1[0]=0; return p;}int main(){ char s1[]="hello "; char s2[]="world"; printf("%s\n", cat(s1,s2)); return 0;}/*hello world*** stack smashing detected ***: ./a.out terminatedAborted (core dumped)*/
因为执行了串的链接操作,所以s1的长度超出了原有的长度限制,为此,我们只需要增加数组的长度即可。s1[20].
实战——模拟森林火势蔓延
一些有用的知识点
多维数组作为参数的时候, 必须指定除了第一维外的所有维的大小。
关于条件判断的良好习惯:
int size;
if(size=1) puts(“right”); // right
if(1=size) puts(“right”); // lvalue required as left operand of assignment
if(1==size) puts(“right”); // no error
如果我们将常数值放在左边则会因为”=”产生提示错误。
ANSI C 中并不包含bool,不过ANSI C99 中包含。
字符串多行表示一种方法是每一行末尾加上“\”,另一种方法是多个”statement”表示
eg:
“please enter the special time you want to check the forest.”
“-1 means your entering end, our start time is 1.”
“if you enter invalid time, the programming will ignore it.”
下面是要达到的模拟效果:
用二维数组代表森林。
自己决定森林的规模和树林的密度。
随机分布树木。
可以设置特殊的时间点(已经燃烧了多少颗树),在时间点上查看森林的情况。
code:
#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <stdbool.h>char forest[100][100];struct point { int x,y;}queue[10010];bool vis[10010];bool look[10010];int front,rear;int x[4]={-1,1,0,0};int y[4]={0,0,-1,1};int plant(int x,int y,int has,int limit){ if(has>limit) has=0; forest[x][y]=has>0?'T':' '; if(forest[x][y]=='T') return 1; return 0;}int Random(int limit){ return (int)((double)rand()/RAND_MAX*limit+0.5);}int get_size(){ int ans=-1; while(ans<1 || ans>100){ puts("enter size of forest (1~100)"); scanf("%d",&ans); } return ans;}int get_probability(){ int ans=-1; while(ans<1 || ans>100){ puts("enter probability of tree (1~100)"); scanf("%d",&ans); } return ans; }void border(int size){ for(int i=0;i<size;i++){ printf("+-"); } puts("+");}void dispaly(int size){ puts(""); border(size); for(int i=0;i<size;i++){ for(int j=0;j<size;j++){ printf("|%c",forest[i][j]); } printf("|\n"); border(size); } puts("");}bool over_border(int x,int y,int size){ if(x>=size || x<0) return 1; if(y>=size || y<0) return 1; return 0;}void bfs(int size,int burnt_tree){ memset(vis,0,sizeof(vis)); while(rear>front){ struct point temp=queue[front++],get; int dex=size*temp.x+temp.y; vis[dex]=1; // it has been burnt for(int i=0;i<4;i++){ int xx=temp.x+x[i]; int yy=temp.y+y[i]; if(over_border(xx,yy,size)) continue; if(forest[xx][yy]=='T') { forest[xx][yy]='*'; get.x=xx; get.y=yy; queue[rear++]=get; burnt_tree++; if(look[burnt_tree]) dispaly(size); } } }}int main(){ int size,pro; int again=1; puts("when you enter 0 for 'again', the programming ended."); srand(time(NULL)); while(again!=0){ front=rear=0; puts("please enter your size and probability."); size=get_size(); pro=get_probability(); // Random create forest. int tree_count=0; for(int i=0;i<size;i++){ for(int j=0;j<size;j++){ tree_count+=plant(i,j,Random(100),pro); } } memset(look,0,sizeof(look)); // the information of forest: printf("the sum of trees: %d, and dispaly as follow:", tree_count); dispaly(size); // inital check time puts("please enter the special time you want to check the forest." "-1 means your entering end, our start time is 1." "if you enter invalid time, the programming will ignore it."); int dex=0,len=size*size; scanf("%d",&dex); while(dex!=-1){ if(dex<0 || dex>=len) ; else look[dex]=1; scanf("%d",&dex); } // Bread,rearth First Search simulate the burning. puts("please enter the burning start location: "); struct point fire; scanf("%d%d",&fire.x,&fire.y); while(over_border(fire.x,fire.y,size)){ scanf("%d%d",&fire.x,&fire.y); } while(tree_count>0 && forest[fire.x][fire.y]!='T'){ puts("your location has not tree. enter fire location again. "); scanf("%d%d",&fire.x,&fire.y); } if(forest[fire.x][fire.y]=='T'){ queue[rear++]=fire; forest[fire.x][fire.y]='*'; } if(look[1]){ dispaly(size); int burnt_tree=1; bfs(size,burnt_tree); } else puts("end."); puts("please enter a value for 'again': "); scanf("%d",&again); } return 0;}/*when you enter 0 for 'again', the programming ended.please enter your size and probability.enter size of forest (1~100)10enter probability of tree (1~100)70the sum of trees: 67, and dispaly as follow:+-+-+-+-+-+-+-+-+-+-+| |T|T| | |T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|T| |T| | | | |+-+-+-+-+-+-+-+-+-+-+|T|T| |T|T|T| |T|T|T|+-+-+-+-+-+-+-+-+-+-+|T|T| |T|T|T|T|T| |T|+-+-+-+-+-+-+-+-+-+-+|T|T| |T|T| | | | |T|+-+-+-+-+-+-+-+-+-+-+|T| |T|T|T|T| | | |T|+-+-+-+-+-+-+-+-+-+-+|T|T| | |T|T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+|T| |T|T|T|T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|T|T|T| | |T| |+-+-+-+-+-+-+-+-+-+-+|T|T|T|T|T| |T|T|T| |+-+-+-+-+-+-+-+-+-+-+please enter the special time you want to check the forest.-1 means your entering end, our start time is 1.if you enter invalid time, the programming will ignore it.1203050-1please enter the burning start location: 5 41 burnt_tree:+-+-+-+-+-+-+-+-+-+-+| |T|T| | |T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|T| |T| | | | |+-+-+-+-+-+-+-+-+-+-+|T|T| |T|T|T| |T|T|T|+-+-+-+-+-+-+-+-+-+-+|T|T| |T|T|T|T|T| |T|+-+-+-+-+-+-+-+-+-+-+|T|T| |T|T| | | | |T|+-+-+-+-+-+-+-+-+-+-+|T| |T|T|*|T| | | |T|+-+-+-+-+-+-+-+-+-+-+|T|T| | |T|T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+|T| |T|T|T|T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|T|T|T| | |T| |+-+-+-+-+-+-+-+-+-+-+|T|T|T|T|T| |T|T|T| |+-+-+-+-+-+-+-+-+-+-+20 burnt_trees:+-+-+-+-+-+-+-+-+-+-+| |T|T| | |T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|T| |T| | | | |+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*|*| |T|T|T|+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*|*|*|T| |T|+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*| | | | |T|+-+-+-+-+-+-+-+-+-+-+|T| |*|*|*|*| | | |T|+-+-+-+-+-+-+-+-+-+-+|T|T| | |*|*|*|T|T|T|+-+-+-+-+-+-+-+-+-+-+|T| |T|*|*|*|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|T|*|T| | |T| |+-+-+-+-+-+-+-+-+-+-+|T|T|T|T|T| |T|T|T| |+-+-+-+-+-+-+-+-+-+-+30 burnt_trees:+-+-+-+-+-+-+-+-+-+-+| |T|T| | |T|T|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|*| |*| | | | |+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*|*| |T|T|T|+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*|*|*|*| |T|+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*| | | | |T|+-+-+-+-+-+-+-+-+-+-+|T| |*|*|*|*| | | |T|+-+-+-+-+-+-+-+-+-+-+|T|T| | |*|*|*|*|T|T|+-+-+-+-+-+-+-+-+-+-+|T| |*|*|*|*|*|T|T|T|+-+-+-+-+-+-+-+-+-+-+| | |T|*|*|*| | |T| |+-+-+-+-+-+-+-+-+-+-+|T|T|T|*|*| |T|T|T| |+-+-+-+-+-+-+-+-+-+-+50 burnt_trees:+-+-+-+-+-+-+-+-+-+-+| |*|*| | |*|*|*|T|T|+-+-+-+-+-+-+-+-+-+-+| | |*|*| |*| | | | |+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*|*| |*|*|*|+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*|*|*|*| |T|+-+-+-+-+-+-+-+-+-+-+|T|T| |*|*| | | | |T|+-+-+-+-+-+-+-+-+-+-+|T| |*|*|*|*| | | |*|+-+-+-+-+-+-+-+-+-+-+|T|T| | |*|*|*|*|*|*|+-+-+-+-+-+-+-+-+-+-+|T| |*|*|*|*|*|*|*|*|+-+-+-+-+-+-+-+-+-+-+| | |*|*|*|*| | |*| |+-+-+-+-+-+-+-+-+-+-+|*|*|*|*|*| |T|T|T| |+-+-+-+-+-+-+-+-+-+-+please enter a value for 'again': 0*/
- ANSI C (2) —— str系列函数
- C语言str函数系列
- C语言str函数系列
- C语言str函数系列
- C语言str函数系列
- C语言str系列函数
- C语言str函数系列总结
- str系列函数
- ANSI C (3) —— 常用系统函数
- c str函数
- ANSI C——printf
- str系列函数的实现
- C语言str系列库函数
- c str常用函数原型
- ANSI C文件操作函数
- R语言——str函数
- C系列函数原型之-StrStr(char *str,char *subStr)的实现
- C++与ANSI C函数原型差异——第七章(P186)
- 红黑树的插入操作详解(插入调整)
- 数塔
- poj2923 Relocation(枚举+01背包)
- 掌控雷电的力量
- CCNA系列三之OSPF路由
- ANSI C (2) —— str系列函数
- 线程的5种状态
- 答案是一样大的,不信?你自己用手指量一下!
- jQuery Mobile 页面
- HDU 5015 233 Matrix
- 有关linux内网渗透的一些笔记
- Android源码中的代理模式解析
- android 中ListView Adapter内所蕴含的观察者模式
- 前段坑积累