C语言进阶篇 三.字符串函数和内存操作函数

目录

字符串函数:

strlen

strcpy

strcat

strcmp

strstr

strtok

strerror

内存操作函数:

memcpy

memmove

memcmp


字符串函数:

求字符串长度

strlen

该函数原型是  size_t strlen ( const char * str );
实现:

size_t strlen ( const char * str)
{
        const char *eos = str;

        while( *eos++ ) ;

        return( eos - str - 1 );
}

该函数实现是从字符指针开始找到第一个‘\0’为止,故用改函数求字符串长度,字符串需以‘\0’结尾,否则求得的长度不可预知。由于返回值是size_t即无符号整形,故用strlen(str1)-strlen(str2)>0并不一定能有效比较str1和str2的长度,因为差值不会为负数。
长度不受限制的字符串函数

strcpy

char* strcpy ( char * destination , const char * source );
实现:
char* strcpy(char* const destination,char const*source)
{
    char* des = destination;
    while ((*destination++ = *source++) != '\0') { }
    return des;
}

字符串拷贝函数,将source开始的字符串全拷贝到destination包括‘\0’,函数实现是从源字符串找到‘\0’,拷贝后停止, 故源字符串必须以 '\0' 结束。
目标空间必须足够大,以确保能存放源字符串,否则就非法访问内存了。
目标空间必须可以改变(不是常量字符串等)。

strcat

原型:char * strcat ( char * destination, const char * source );

字符串追加函数,实现:

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

        while( *cp )
                cp++;                   /* find end of dst */

        while((*cp++ = *src++) != '\0') ;       /* Copy src to end of dst */

        return( dst );                  /* return dst */

}

先找到目标字符串的‘\0’然后从‘\0’开始追加至源字符串的‘\0’也拷贝过去为止,故目标空间必须有足够大的空间,能容纳下源字符串的内容。 目标空间必须可修改。源字符串必须以 '\0' 结束。

strcmp

int strcmp ( const char * str1, const char * str2 );

依次比较两个字符串各个字符的ASCII码值,返回值规定如下:

标准规定:

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于 0 的数字
实现:
int  strcmp (const char * src, const char * dst)
{
        int ret = 0 ;

        while((ret = *(unsigned char *)src - *(unsigned char *)dst) == 0 && *dst)
                {
                ++src, ++dst;
                }

        return ((-ret) < 0) - (ret < 0); // (if positive) - (if negative) generates 
                                                              //branchless code
//将返回值限定在0,1,-1
}

长度受限制的字符串函数介绍

strncpy

char * strncpy ( char * destination, const char * source, size_t num );

strncat

char * strncat ( char * destination, const char * source, size_t num );

strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

与上述长度受限制的字符串函数类似,不过多了一个参数num :字符个数,可以指定操作的字符个数。

字符串查找

strstr

在母串中查找子串的函数,会返回找到的第一个子串的字符指针。

函数实现:(原始方法查找子串,比KMP,sunday等算法效率低)

从字符串str1中查找字符串str2

char *  strstr (const char * str1,const char * str2)
{
        char *cp = (char *) str1;
        char *s1, *s2;

        if ( !*str2 ) 子串str2为空,返回母串
            return((char *)str1);

        while (*cp)
        {
                s1 = cp;母串指针
                s2 = (char *) str2;子串指针

                while ( *s2 && !(*s1-*s2) )
                        s1++, s2++;

                if (!*s2)若子串指针指向‘\0’,查找成功,返回对应母串位置
                        return(cp);

                cp++;
        }

        return(NULL);

}

字符串切割函数

strtok

原型:

例如两字符串:

char string[] = "A string\tof ,,tokens\nand some  more tokens";
char seps[]   = " ,\t\n";

使用方法

 printf( "%s\n\nTokens:\n", string );
   /* Establish string and get the first token: */
   token = strtok( string, seps );
   while( token != NULL )
   {
      /* While there are tokens in "string" */
      printf( " %s\n", token );
      /* Get next token: */
      token = strtok( NULL, seps );//传入NULL,函数将从上次'\0'后的位置开始切割
   }

 用该函数每次切割后该函数都将返回切割前的地址,并修改原字符串切割字符为'\0',下次切割将从‘\0’开始,这样依次打印会得到

 A
 string
 of
 tokens
 and
 some
 more
 tokens

错误信息报告

strerror

传入错误码errno,该函数返回错误信息字符串的首地址,用来打印错误信息

内存操作函数:

memcpy

内存拷贝函数,定义:

void * memcpy ( void * destination , const void * source , size_t num );
参数num是拷贝的字节数,函数实现是逐字节拷贝的。
模拟实现

C语言进阶篇 三.字符串函数和内存操作函数_第1张图片

函数 memcpy source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。
这个函数在遇到 '\0' 的时候并不会停下来。
如果 source destination 有任何的重叠,复制的结果都是未定义的(使用memmove函数)

memmove

与memcpy类似,但是功能更强大,可以实现destination和source重叠的拷贝,因为函数实现是从重叠的区域开始拷贝的。

模拟实现

C语言进阶篇 三.字符串函数和内存操作函数_第2张图片

memcmp

int memcmp ( const void * ptr1 , const void * ptr2 , size_t num );

逐字节比较两内存区域,类似strcmp函数比较的是对应数据的ASCII码值。

实现:

int memcmp(char* buf1,char *buf2,unsigned count)
{
    if (!count)
        return(0);
    while (--count && *buf1 == *buf2)
    {
        buf1++;
        buf2++;
    }
    return(*buf1 - *buf2);
}

你可能感兴趣的:(C语言,c语言,开发语言)