zoukankan      html  css  js  c++  java
  • C语言字符串处理函数

    C语言字符串处理函数

    http://blog.csdn.net/ruizeng88/article/details/6677736
     
     

    1.字符串比较

    int strcmp(const char *s1, const char *s2);

    比较两个字符串的大小(不忽略大小写),返回值很有学问:如果s1小于s2返回一个小于0的数,如果s1大于s2返回一个大于0的数,如果相等则返回0。返回值是两个字符串中第一个不相等的字符ascii码的差值。实现如下:

     

    1. int my_strcmp(const char *s1, const char *s2){  
    2.     //important! validate arguments first!   
    3.     assert(NULL !=s1 && NULL != s2);  
    4.     while(*s1 != '' && *s2 != '' && *s1==*s2){  
    5.         s1++;  
    6.         s2++;  
    7.     }  
    8.     return *s1 - *s2;  
    9. }  
    int my_strcmp(const char *s1, const char *s2){
    	//important! validate arguments first!
    	assert(NULL !=s1 && NULL != s2);
    	while(*s1 != '' && *s2 != '' && *s1==*s2){
    		s1++;
    		s2++;
    	}
    	return *s1 - *s2;
    }

    注意再函数开始进行参数检查,防止输入参数有NULL时发生运行时错误。

    strcmp是最常用的字符串比较函数,一般用法是if(!strcmp(s1, s2)){ ...}。如果不是对整个字符串进行比较而只是比较指定数目的字符串,可以使用函数:

    int strncmp(const char *s1, const char *s2, size_t n);

    用法和返回值都和strcmp类似,之比较给定字符串的前n个字符,或者到遇到任一字符串结尾。实现如下:

     

    1. int my_strncmp(const char *s1, const char *s2, size_t n){  
    2.     //important! validate arguments first!   
    3.     assert(NULL!=s1 && NULL!=s2);  
    4.     if(n == 0)  
    5.         return 0;  
    6.     size_t cnt = 1;  
    7.     while(*s1 != '' && *s2 != '' && *s1==*s2 && cnt < n){  
    8.         s1++;  
    9.         s2++;  
    10.         cnt++;  
    11.     }  
    12.     return *s1 - *s2;  
    13. }  
    int my_strncmp(const char *s1, const char *s2, size_t n){
    	//important! validate arguments first!
    	assert(NULL!=s1 && NULL!=s2);
    	if(n == 0)
    		return 0;
    	size_t cnt = 1;
    	while(*s1 != '' && *s2 != '' && *s1==*s2 && cnt < n){
    		s1++;
    		s2++;
    		cnt++;
    	}
    	return *s1 - *s2;
    }
    需要注意的除了参数检查外,还要注意n=0的特殊情况,这里我们n=0永远返回0。

    还有其他一些带特殊要求字符串比较函数,如:

    stricmp,memcmp,memicmp等等,加i表示比较时忽视大小写,带mem的是比较一块内存区间。

    2.字符串查找

    最简单的是查找字符串查找字符:

    char *strchr(const char *s, int c);

    至于参数为什么是int,历史遗留问题,这里不多讨论。函数返回在s中找到的第一个c的位置的指针,注意的是,字符串末尾的‘’也是可以被查找的。实现如下:

    1. char *my_strchr(const char *s, int n){  
    2.     assert(s != NULL);  
    3.     char c = (char)n;  
    4.     do{  
    5.         if(*s == c)  
    6.             return (char *)s;  
    7.     }while(*s++);  
    8.     return NULL;  
    9. }  
    char *my_strchr(const char *s, int n){
    	assert(s != NULL);
    	char c = (char)n;
    	do{
    		if(*s == c)
    			return (char *)s;
    	}while(*s++);
    	return NULL;
    }
    还有查找字符串的函数strstr:

    char *strstr(const char *s1, const char *s2);

    函数返回s2在s1中出现的首字符的位置,实现如下:

    1. char *my_strstr(const char *s1, const char *s2){  
    2.     assert(NULL!=s1 && NULL!=s2);  
    3.     size_t len = strlen(s2);  
    4.     while(*s1){  
    5.         if(!strncmp(s1,s2,len))  
    6.             return (char *)s1;  
    7.         s1++;  
    8.     }  
    9.     return NULL;  
    10. }  
    char *my_strstr(const char *s1, const char *s2){
    	assert(NULL!=s1 && NULL!=s2);
    	size_t len = strlen(s2);
    	while(*s1){
    		if(!strncmp(s1,s2,len))
    			return (char *)s1;
    		s1++;
    	}
    	return NULL;
    }

    c标准库中并没有定义类似strnchr和strnstr的限定查找范围的函数,当然需要的话我们可以自己定义,如:

    1. char *strnstr(const char* s1, const char* s2, size_t n)  
    2. {  
    3.   const char* p;  
    4.   size_t len = strlen(s2);  
    5.   if (len == 0) {  
    6.     return (char *)s1;  
    7.   }  
    8.   for (p = s1; *p && (p + len<= buffer + n); p++) {  
    9.     if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {  
    10.       return (char *)p;  
    11.     }  
    12.   }  
    13.   return NULL;  
    14. }  
    char *strnstr(const char* s1, const char* s2, size_t n)
    {
      const char* p;
      size_t len = strlen(s2);
      if (len == 0) {
        return (char *)s1;
      }
      for (p = s1; *p && (p + len<= buffer + n); p++) {
        if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {
          return (char *)p;
        }
      }
      return NULL;
    }
    3.字符串复制

    最常见的字符串复制函数是strcpy:

    char *strcpy(char *dst, const char *src);

    把src所指的由NULL结尾的字符串复制到由dst所指的字符串中,src和dst不可以相同(可以由c99的restrict关键字声明),dst必有足够的空间存放复制的字符串。

    还有一点要注意的是函数返回值,返回值是指向dst的指针,这样做的目的是方便程序中语句内联,比如strlen(strcpy(s,t))。

    函数的实现如下:

    1. char *my_strcpy(char *dst, const char *src){  
    2.     assert(NULL!=dst && NULL!=src);  
    3.     char *p = dst;  
    4.     while((*dst++ = *src++) != '');  
    5.     return p;  
    6. }  
    char *my_strcpy(char *dst, const char *src){
    	assert(NULL!=dst && NULL!=src);
    	char *p = dst;
    	while((*dst++ = *src++) != '');
    	return p;
    }

    使用strcpy是危险的,因为函数本身是不检查dst指向的空间是否足够存储需要复制的字符串,导致的一个潜在隐患就是字符串溢出。这也是上个世纪常被黑客利用的一个经典漏洞。所以,在大多数情况下都是用strncpy无疑更加保险:

    1. char *my_strncpy(char *dst, const char *src, size_t n){  
    2.     assert(NULL!=dst && NULL!=src);  
    3.     char *p = dst;  
    4.     while(n){  
    5.         if((*dst++ = *src++) == '')  
    6.             break;  
    7.         n--;  
    8.     }  
    9.     return p;  
    10. }  
    char *my_strncpy(char *dst, const char *src, size_t n){
    	assert(NULL!=dst && NULL!=src);
    	char *p = dst;
    	while(n){
    		if((*dst++ = *src++) == '')
    			break;
    		n--;
    	}
    	return p;
    }

    需要注意另外一个函数strdup:

    char *strdup(const char *);

    该函数和strcpy的不同是,函数会自己申请内存空间存放拷贝的字符串,然后返回指向该字符串的指针。所以在使用strdup函数时需要注意的是,在使用完复制的字符串后使用free函数释放其占用的空间。

    另memcpy函数和strncpy类似,只是不会再遇到NULL时终止拷贝,该函数一定会拷贝n个字符。

     

    4.字符串连接

    字符串连接是把一个字符串的头连接到另一个字符串的结尾。

    char *strcat(char *s1, const char *s2);

    函数的实现如下:

    1. char *my_strcat(char *s1, const char *s2){  
    2.     assert(NULL!=s1 && NULL!=s2);  
    3.     char *p =s1;  
    4.     while(*s1)s1++;  
    5.     strcpy(s1,s2);  
    6.     return p;  
    7. }  
    char *my_strcat(char *s1, const char *s2){
    	assert(NULL!=s1 && NULL!=s2);
    	char *p =s1;
    	while(*s1)s1++;
    	strcpy(s1,s2);
    	return p;
    }

    同样,strcat也是不安全的,因为也对缓冲区足够存放连接的字串进行了假设。所以,多数情况下我们应该使用更安全的:

    char *strncat(char *s1, const char *s2, size_t n

    -------------------------------------

    归类自己需要的资料,慢慢爬行

    C语言中的字符串截取函数及应用


    /*========================================================

    对于一个五位数a1a2a3a4a5,可将其拆分为三个子数:
    sub1=a1a2a3
    sub2=a2a3a4
    sub3=a3a4a5
    例如,五位数20207可以拆分成
    sub1=202
    sub2=020(=20)
    sub3=207
    现在给定一个正整数K,要求你编程求出10000到30000之间所有满足下述条件的五位数,
    条件是这些五位数的三个子数sub1,sub2,sub3都可被K整除。
    输入
    输入由键盘输入,输入仅一行,为正整数K(0<K<1000)。
    输出
    输出到文件,输出文件的每一行为一个满足条件的五位数,要求从小到大输出。
    不得重复输出或遗漏。如果无解,则输出“No”。

    样例
    num.in
    15
    num.out
    22555
    25555
    28555
    30000

    ==========================================================*/


    #include <stdio.h>
    #include <string.h>

    /*从字符串的左边截取n个字符*/
    char * left(char *dst,char *src, int n)
    {
        char *p = src;
        char *q = dst;
        int len = strlen(src);
        if(n>len) n = len;
        /*p += (len-n);*/   /*从右边第n个字符开始*/
        while(n--) *(q++) = *(p++);
        *(q++)=''; /*有必要吗?很有必要*/
        return dst;
    }

    /*从字符串的中间截取n个字符*/
    char * mid(char *dst,char *src, int n,int m) /*n为长度,m为位置*/
    {
        char *p = src;
        char *q = dst;
        int len = strlen(src);
        if(n>len) n = len-m;    /*从第m个到最后*/
        if(m<0) m=0;    /*从第一个开始*/
        if(m>len) return NULL;
        p += m;
        while(n--) *(q++) = *(p++);
        *(q++)=''; /*有必要吗?很有必要*/
        return dst;
    }

    /*从字符串的右边截取n个字符*/
    char * right(char *dst,char *src, int n)
    {
        char *p = src;
        char *q = dst;
        int len = strlen(src);
        if(n>len) n = len;
        p += (len-n);   /*从右边第n个字符开始*/
        while(*(q++) = *(p++));
        return dst;
    }

    void main()
    {
        FILE * p;
        int i,k,outi,count=0;
        int sub1,sub2,sub3;
        char *strsub1,*strsub2,*strsub3,*strtempnum,*a,*b,*c;

        if((p = fopen("num.out", "ab+")) == NULL)
        {
            printf("open file fail!");
            getch();
            exit();
        }
        printf("Please input int number(0<K<1000):");
        scanf("%d",&k);

        for(outi=10000;outi<=30000;outi++)
        {
            itoa(outi,strtempnum,10);

            left(strsub1,strtempnum,3);
            mid(strsub2,strtempnum,3,1);
            right(strsub3,strtempnum,3);

            /*
            a=strsub1;
            b=strsub2;
            c=strsub3;
            printf("strsub1=%s,strsub2=%s,strsub3=%s ",a,b,c);
            */

            sub1=atoi(strsub1);
            sub2=atoi(strsub2);
            sub3=atoi(strsub3);

            /*
            printf("sub1=%d , sub2=%d , sub3=%d ",sub1,sub2,sub3);
            printf("sub1k=%d , sub2k=%d , sub3k=%d " , sub1 % k,sub2 % k,sub3 % k);
            getch();
            */
            if((sub1%k)==0 && (sub2%k)==0 && (sub3%k)==0)
            {
                fprintf(p,"%d ",outi);
                count++;
                printf("outi=%d ",outi);
            }
            else
            {
                fprintf(p,"%s ","NO");
            }
        }
        printf("Count=%d    OK",count);
        fclose(p);
        getch();
    }

     http://www.cnblogs.com/rosesmall/archive/2012/03/27/2420335.html

  • 相关阅读:
    取消GridView/ListView item被点击时的效果 记录学习
    EditText 几种显示方式,固定行数,自适应行数
    Android 判断当前屏幕是横屏还是竖屏
    Android 用代码设置Shape,corners,Gradient
    Android 横屏不让输入法全屏显示
    js-JavaScript高级程序设计学习笔记7
    js-FCC算法-Pairwise
    js-JavaScript高级程序设计学习笔记6
    js-JavaScript高级程序设计学习笔记5
    js-自制轮播插件!
  • 原文地址:https://www.cnblogs.com/kungfupanda/p/3926772.html
Copyright © 2011-2022 走看看