字符串处理函数的小结

首先讨论一个有关的话题,关于字符串结束符:'\0':

1、‘\0’是转移字符,意思是告诉程序,这不是字符0;

2、'\0'在内存里就是8位的00000000,而0则是'\0'的ASCII码表示,是第一个ASCII码,也叫NUL,数字0的ASCII码是48。

3,、在调试程序时,'\0'可以看到在内存里面是0,这是ASCII码的表示,也可以看作是一个unsigned int类型。
NUL: 0x000值字符,用于结束ASCII字符串,和'\0'类似(可以理解为别名),但是在c/c++中没有定义,如果要使用的话,需要自定义为 #define NUL '\0';
NULL: 定义为00L(void *)0,用于指示一个指针值是空,即什么都不指;

NULL是在<stddef.h>头文件中专门为空指针定义的一个宏。NULASCII字符集中第一个字符的名称,它对应于一个零值。C语言中没有NUL这样的预定义宏。注意:在ASCII字符集中,数字0对应于十进制值48,不要把数字0'\0'(NUL)的值混同起来。

NULL可以被定义为(void *)0,而NUL可以被定义为'\0'NULLNUL都可以被简单地定义为0,这时它们是等价的,可以互换使用,但这是一种不可取的方式。为了使程序读起来更清晰,维护起来更容易,你在程序中应该明确地将NULL定义为指针类型,而将NUL定义为字符类型。

字符串操作函数的列表链接:http://see.xidian.edu.cn/cpp/u/hs2/

1.strcpy函数:

具体实现:

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

{
          char * cp = dst;
        while( *cp++ = *src++ );               /* Copy src over dst */
        return( dst );
}

存在问题分析:

1.如果源字符串的空间大于目标字符串的空间,有可能出现对未分配内存区域进行写的情况;


2.strncpy函数:为了解决上面的问题,引入了这个strncpy函数

具体实现:

char * __cdecl strncpy ( char * dest, const char * source, size_t count)
{
        char *start = dest;

        while (count && (*dest++ = *source++))    /* copy string */
                count--;

        if (count)                              /* pad out with zeroes */
                while (--count)
                        *dest++ = '\0';
        return(start);
}

存在问题分析:

1、如果count的大小大于dest的长度,那么还是会出现上面所说的对未分配内存进行写操作的情况,所以在调用的时候,调用者自己必须清楚这个问题。

2、如果count的大小为n,而source的长度大于n,dest的空间长度也大于n,那么在拷贝完成后,dest里面的内容会缺少字符串结束符'\0',

(例如count为3,source为“qwert”,dest为“yuiop”,则dest里面的内容为'qweop',在e后面没有字符结束标志字符'\0'。所以需要开发者手动加入'\0'到dest中。


3.strcmp函数:

具体实现:

int __cdecl strcmp (
        const char * src,
        const char * dst
        )
{
        int ret = 0 ;


        while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
                ++src, ++dst;


        if ( ret < 0 )
                ret = -1 ;
        else if ( ret > 0 )
                ret = 1 ;


        return( ret );
}

4.strncmp函数

具体实现:

int __cdecl strncmp ( const char * first, const char * last, size_t count)
{
        if (!count)
                return(0);


        while (--count && *first && *first == *last)
        {
                first++;
                last++;
        }


        return( *(unsigned char *)first - *(unsigned char *)last );
}

/*

*Exit:
*       returns <0 if first < last
*       returns  0 if first == last
*       returns >0 if first > last

*/

分析:该函数需要注意的地方是返回值,当*first>*last的时候,返回值是一个>0的数,当*first<*last的时候,返回值是一个<0的数


5.strcat函数

具体实现:

char * __cdecl strcat (char * dst, const char * src)
{
        char * cp = dst;

        while( *cp )
                cp++;                   /* find end of dst */
        while( *cp++ = *src++ ) ;       /* Copy src to end of dst */
        return( dst );                  /* return dst */
}

问题分析:

strcat函数可能存在对dst开始的后面实际未分配的地址进行写操作的可能。


6.strncat

具体实现:

char * __cdecl strncat (char * front, const char * back, size_t count)
{
        char *start = front;
        while (*front++)
                ;
        front--;
        while (count--)
                if (!(*front++ = *back++))
                        return(start);
        *front = '\0';
        return(start);
}

问题分析:该函数保证了front字符串始终以'\0'结尾,但是count的选择还是要自己注意,也有可能出现越界写内存的可能。

7.strnicmp用于windows程序中,对应linux下面的函数名是strncasecmp:

功能:还是比较两个字符串中前n个数字的大小,只不过忽略大小写,即同一个字母的大写和小写看着是相等的。

具体实现:

int __cdecl _strnicmp (
        const char * first,
        const char * last,
        size_t count
        )
{
        int f,l;
#ifdef _MT
        int local_lock_flag;
#endif  /* _MT */


        if ( count )
        {
#if defined (_WIN32)
            if ( __lc_handle[LC_CTYPE] == _CLOCALEHANDLE ) {
#endif  /* defined (_WIN32) */


                do {
                    if ( ((f = (unsigned char)(*(first++))) >= 'A') &&
                         (f <= 'Z') )
                        f -= 'A' - 'a';


                    if ( ((l = (unsigned char)(*(last++))) >= 'A') &&
                         (l <= 'Z') )
                        l -= 'A' - 'a';


                } while ( --count && f && (f == l) );
#if defined (_WIN32)
            }
            else {
                _lock_locale( local_lock_flag )


                do {
                    f = _tolower_lk( (unsigned char)(*(first++)) );
                    l = _tolower_lk( (unsigned char)(*(last++)) );
                } while (--count && f && (f == l) );


                _unlock_locale( local_lock_flag )
            }
#endif  /* defined (_WIN32) */


            return( f - l );
        }


        return( 0 );
}

8.strtok和strtok_r函数:

函数实现:

  1. char *strtok_r(char *s, const char *delim, char **save_ptr) {  
  2.     char *token;  
  3.   
  4.     if (s == NULL) s = *save_ptr;  
  5.   
  6.     /* Scan leading delimiters.  */  
  7.     s += strspn(s, delim);  
  8.     if (*s == '\0')   
  9.         return NULL;  
  10.   
  11.     /* Find the end of the token.  */  
  12.     token = s;  
  13.     s = strpbrk(token, delim);  
  14.     if (s == NULL)  
  15.         /* This token finishes the string.  */  
  16.         *save_ptr = strchr(token, '\0');  
  17.     else {  
  18.         /* Terminate the token and make *SAVE_PTR point past it.  */  
  19.         *s = '\0';  
  20.         *save_ptr = s + 1;  
  21.     }  
  22.   
  23.     return token;  
  24. }  


  1. char *strtok(char *s, const char *delim)  
  2. {  
  3.     static char *last;  
  4.   
  5.     return strtok_r(s, delim, &last);  
  6. }  

见下面两个链接:

http://blog.csdn.net/liuintermilan/article/details/6280816

http://blog.csdn.net/liuintermilan/article/details/6283705


9.strpbrk函数:

功能描述:依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,则停止检验,并返回该字符位置,空字符NULL不包括在内。

具体实现:

extern char *strpbrk(const char *s1, const char *s2);
char * strpbrk(const char * cs,const char * ct)
{
const char *sc1,*sc2;
for( sc1 = cs; *sc1 != '\0'; ++sc1) {
for( sc2 = ct; *sc2 != '\0'; ++sc2) {
if (*sc1 == *sc2)
return (char *) sc1;
}
}
return NULL;
}

10.strchr:

功能描述:查找字符串s中首次出现字符c的位置

函数实现:

char * strchr ( char * s, char c)
{
   while (*s != '\0' && *s != c)
   {
     ++s;
   }
   return *s == c ?s:NULL;
}

11.strstr:
函数原型:extern char *strstr(const char *str1, const char *str2);
功能描述:该函数返回str2第一次在str1中的位置,如果没有找到,返回NULL
具体实现:
char *
  strstr (constchar*s1,constchar*s2)
 {
 constchar*p=s1;
 constsize_tlen= strlen (s2);
  for (;(p= strchr (p,*s2))!=0;p++)
 {
  if ( strncmp (p,s2,len)==0)
  return ( char *)p;
 }
return (0);
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值