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*/
0 0
原创粉丝点击