C语言中常用到的字符串库函数

目录

1. strlen

2. strcpy

3. strcat

4. strcmp

5. strncpy

6. strncat

7. strncmp

8. strstr

9. strerror

10. memcpy

11. memmove

12. memcmp

1. strlen

size_t strlen( const char *string );

作用获取字符串的长度

解释字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含'\0')

注意:

  1. 参数指向的字符串必须要以 '\0' 为结尾,否则会返回随机数
  2. 注意函数的返回值为size_t,是无符号

模拟实现:

//计数方式
int my_strlen(const char* str)
{
    assert(str);
    int count = 0;

    while(*str)
    {
        count++;
        str++;
    }

    return count;
}

//递归方式
int my_strlen(const char* str)
{
    assert(str);
    if(*str)
    {
        return 0;
    }
    else
    {
        return 1 + my_strlen(str + 1);
    }
}

//指针-指针方式
int my_strlen(const char* str)
{
    assert(str);
    char* p = str;

    while(*p)
    {
        p++;
    }

    return p - str
}

2. strcpy

char *strcpy( char *strDestination, const char *strSource );

作用复制字符串 

解释源字符串必须以 '\0' 结束,也会将 '\0' 拷贝到目标空间

注意:

  1. 目标空间必须足够大,确保能够存放源字符串
  2. 目标空间必须可变

模拟实现:

char *my_strcpy(char *dest, const char*src)
{
    char *ret = dest;
    assert(dest != NULL);
    assert(src != NULL);

    while((*dest++ = *src++))
    {
        ;
    }

    return ret;
}

3. strcat

char * strcat ( char * destination, const char * source );

作用追加字符串

解释在源字符串后追加目标字符串

注意:

  1. 源字符串必须以 '\0' 结束
  2. 目标空间必须足够大
  3. 目标空间必须可以修改

模拟实现:

char *my_strcat(char *dest, const char*src)
{
    char *ret = dest;
    assert(dest != NULL);
    assert(src != NULL);

    while(*dest)
    {
        dest++;     //先找到源字符串的 '\0'
    }
    while((*dest++ = *src++))
    {
        ;           //进行追加
    }

    return ret;
}

4. strcmp

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

作用比较两个字符串

解释strcmp()函数首先将str1字符串的第一个字符的ACSII值减去str2第一个字符的ACSII值(自左向右逐个字符相比,直到出现不同的字符或遇'\0'为止)若差值为零则继续比较下去;若差值不为零,则返回差值

注意:

  1. strcmp可用于比较两个字符串常量或比较数组和字符串常量,不能比较数字等其他形式的参数。

模拟实现:

//第一个字符串大于第二个字符串,则返回大于0的数字
//第一个字符串等于第二个字符串,则返回0
//第一个字符串小于第二个字符串,则返回小于0的数字
int my_strcmp (const char * src, const char * dst)
{
    int ret = 0 ;
    assert(src != NULL);
    assert(dest != NULL);

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

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

    return (ret);
}

5. strncpy

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

作用拷贝num个字符从源字符串到目标空间

解释和strcpy类似

注意:

  1. 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个

6. strncat

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

作用追加num个字符从源字符串到目标空间后

解释和strcat类似

注意:

  1. 如果源中 C 字符串的长度小于 num,则只有终止之前的内容复制空字符

7. strncmp

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

作用比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完

解释和strcmp类似

注意:

8. strstr

char * strstr ( const char *str1, const char * str2);

作用查找子字符串

解释查找 str1 中是否有 str2

注意:

模拟实现:

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

    if ( !*str2 )
    {
        return((char *)str1);
    }
 
    while (*cp)
    {
        s1 = cp;
        s2 = (char *) str2;

        while ( *s1 && *s2 && !(*s1-*s2) )
        {
            s1++;
            s2++;
        }    
 
        if (!*s2)
        {
            return(cp);
        }
 
        cp++;
    }
 
    return(NULL);
}

9. strerror

char * strerror ( int errnum );

作用获取系统错误消息 (strerror) 或打印用户提供的错误消息 (_strerror)。

解释返回错误码,所对应的错误信息。

注意:

        字符分类函数:

         函数           如果它的参数符合下列条件就返回真

  1. iscntrl        任何控制字符
  2. isspace     空白字符:空格‘ ’,换页‘\f’,换行'\n',回车'\r',制表符'\t',或垂直制表符'\v'
  3. isdigit        十进制数字0~9
  4. isxdigit      十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
  5. islower      小写字母a~z
  6. isupper     大写字母A~Z
  7. isalpha     字母a~z或A~Z
  8. isalnum    字母或数字a~z,A~Z或0~9
  9. ispunct     标点符号,任何不属于数字或字母的图像字符(可打印符号)
  10. isgraph     任何图像字符

        字符转换:

  1. int tolower ( int c );  //大写字符转小写字符
  2. int toupper ( int c ); //小写字符转大写字符

##案例##:

#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main ()
{
    FILE * pFile;
    pFile = fopen ("unexist.ent","r");

    if (pFile == NULL)
    {
        printf ("Error opening file unexist.ent: %s\n",strerror(errno));
    }
        //errno: Last error number
    return 0;
}

10. memcpy

void * memcpy ( void * destination, const void * source, size_t num );

作用拷贝任何数据类型的对象,并指定拷贝的数据长度

解释由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内

注意:

  1. source和destination所指内存区域不能重叠,函数返回指向destin的指针。
  2. 与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节
  3. 如果目标数组destination本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。

  4. 如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。

  5. source和destination都不一定是数组,任意的可读写的空间均可。

模拟实现:

void * memcpy ( void * dst, const void * src, size_t count)
{
    void * ret = dst;
    assert(dst);
    assert(src);

    /*
    * copy from lower addresses to higher addresses
    */

    while (count--) 
    {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
    }

    return(ret);
}

11. memmove

void *memmove( void *dest, const void *src, size_t count );

作用将src移动到dest。

解释和memcpy比较,他们的作用是一样的,唯一的区别是,当内存发生局部重叠的时候, memmove 保证拷贝的结果是正确的, memcpy 不保证拷贝的结果的正确。

注意:

  1. 如果要去实现memmove函数的话,需要考虑 src 在 dest 前面和后面两种情况是否一样,并如何实现。

模拟实现:

void* my_memmove(void *det, const void *src, int num)
{
    assert(det && src);
    char* p1 = (char*)det;
    char* p2 = (char*)src;
    if(det < src)
    {
        while(num--)
        {
            *p1 = *p2;
            p1++;
            p2++;
        }
    }
    else
    {
        p1 += num;
        p2 += num;
        while(num--)
        {
            *p1 = *p2;
            p1--;
            p2--;
        }
    }

    return p1;
}

12. memcmp

int memcmp( const void *buf1, const void *buf2, size_t count );

作用比较两个指针后count个字节

解释比较从buf1和buf2指针开始的count个字节 ( 和strncmp类似 )

注意:

  1. 对于memcmp(),如果两个字符串相同而且count大于字符串长度的话,memcmp不会在\0处停下来,会继续比较\0后面的内存单元,直到_res不为零或者达到count次数。

##案例##:

//当buf1<buf2时,返回值<0
//当buf1=buf2时,返回值=0
//当buf1>buf2时,返回值>0
#include <stdio.h>
#include <string.h>
int main ()
{
    char buffer1[] = "DWgaOtP12df0";
    char buffer2[] = "DWGAOTP12DF0";
    int n;
    n=memcmp ( buffer1, buffer2, sizeof(buffer1) );

    if (n>0) 
    {
        printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
    }
    else if (n<0) 
    {
        printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
    }
    else 
    {
        printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
    }

    return 0;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值