C语言中字符串相关的函数解析

        C语言中没有string类型,字符串通常放在常量字符串字符数组中,下面来介绍一些常用的字符串相关的操作函数。

strlen

        strlen用来求一个字符串的长度,其函数原型如下:

size_t strlen ( const char * str );

        使用strlen需要注意以下几点:

①strlen求的是字符串中\0前面的字符个数(不包括\0),所以字符串必须\0结尾

②strlen返回值类型是size_t,也就是unsigned int,是无符号整型,如果两个strlen相减是不能得到负数的。

        下面用两种方法来模拟实现一下strlen:

//方法1,常规方法
  int My_Strlen(char *str)
  {
   int num = 0;
   while (*str != '\0')
   {
       num++;
       str++;
   }
   return num;
  }
 //方法2,递归
  int My_Strlen_1(char *str)
  {
   if (*str != '\0')
   {
       return My_Strlen_1(str + 1) + 1;//这里不能用str++,因为后置++是先执行再++,会死循环,++str也不推荐,虽然可以实现,但是str也被改变了
   }
   return 0;
  }

strcpy

        strcpy用于拷贝源空间的字符串到目标空间,其函数原型如下:

//source是源字符串首地址,Destination是目标字符串首地址,返回的是目标字符串的首地址
char* strcpy(char * destination, const char * source);

        使用该函数需要注意以下几点:

①源字符串必须以\0结尾。

②该函数会把源字符串中\0之前的字符连同\0一起拷贝到目标地址。

③目标空间必须足够大,保证能存放源字符串

④目标空间必须是可变的,不能是常量字符串。

        下面来模拟实现一下strcpy:

/*
 * @brief    拷贝字符串初阶代码
 * @param    dest: 要拷贝的目标地址
 * @param    src: 要拷贝的源地址
 */
void my_strcpy(char *dest, char *src)
{
    while (*src != '\0') // 判断scr还没有结束
    {
        *dest = *src; // 把src中的字符复制到dest中
        dest++;
        src++;
    }
    *dest = *src; // strcpy会把\0也一起拷贝
}
/*
 * @brief    改进的字符串拷贝函数
 * @param    dest: 要拷贝的目标地址
 * @param    src: 要拷贝的源地址
 * @return   char*: 返回目标空间的起始地址,也就是最初的dest
 */
// 增加返回值是为了实现链式访问,函数的返回值可以作为其他函数的参数
char *my_strcpy_01(char *dest, const char *src) // 在源地址加入const是为了防止写函数时while等号两边写反,如果加上const,写反会报错
{
    char *ret = dest;
    assert(dest && src);             // 增加断言,防止输入参数误传为NULL,如果误传会报错
    while (*dest++ = *src++) ;// 较上述代码有所简化,当*src为\0时,赋值后表达式会为0,会跳出循环
    return ret;
}

strcat

        strcat用于在目标字符串后追加源字符串,其函数原型如下:

//source是源字符串地址,destination是目标字符串地址,返回的是目标字符串地址
char * strcat ( char * destination, const char * source );

        使用该函数需要注意以下几点:

①源字符串必须以\0结尾。

②目标空间必须足够大,保证能存放源字符串

③目标空间必须是可变的,不能是常量字符串。

         下面举一个使用示例:

int main()
{
    char arr[20] = "hello ";
    strcat(arr,"world");
    printf("%s\n",arr);//会打印hello world
}

        下面来模拟实现一下strcat:

/*
 * @brief    字符串追加函数
 * @param    destination:目标字符串地址
 * @param    source:源字符串地址
 * @return   char*:返回目标字符串地址
 */
char *my_strcat(char *destination, const char *source)
{
    assert(destination && source);//断言防止输入NULL
    char *dest = destination;
    while (*destination++) ;// 先找出目标字符串的末尾,也就是\0
    destination--;                     // 此时destination就是\0的位置
    while (*destination++ = *source++) ;// 然后与字符串拷贝同理
    return dest;
}

strcmp

        strcmp用于比较两个字符串是否相等,比较的是每一个字符的ASCII码值的大小,其函数原型如下:

//str1是第一个字符串的地址,str2是第二个字符串的地址,
//如果第一个字符串大于第二个字符串,返回大于0的数,如果小于,返回小于0的数,如果等于,返回0
int strcmp ( const char * str1, const char * str2 );

        下面举一个例子:

int main()
{
    char arr1[10] = "abc";
    char arr2[20] = "abc";
//这样比较两个字符串是否相等是不对的,因为arr1和arr2是数组名,就是数组首元素的地址,直接用等号比比的是地址的大小,而不是两个字符串相比
    if(arr1 == arr2)
        printf("arr1 == arr2\n");
    else
        printf("arr1 != arr2\n");
//判断两个字符串是否相等应该用下面的方法,并且strcmp比较的不是字符串的长度,而是ASCII码,abc是比abbbbbbb要大的
    if(strcmp(arr1,arr2) > 0)
        printf("arr1 > arr2\n");
    else if(strcmp(arr1,arr2) < 0)
        printf("arr1 < arr2\n");
    else
        printf("arr1 == arr2\n");
}

         下面来模拟实现一下strcmp:

/*
 * @brief    字符串比较函数,如果str1>str2,输出正数,反之输出负数,相等输出0,比较的不是长度,是ASCll码
 * @param    str1:
 * @param    str2:
 * @return   int:
 */
int my_strcmp(const char *str1, const char *str2)
{
    assert(str1 && str2);
    // 遍历两字符串,如果找到不相等的退出循环,输出不相等字符串的差,如果两字符串都相等*str1=*str2会为\0,输出差值为0
    while ((*str1 == *str2) && (*str1))
    {
        str1++;
        str2++;
    }
    return *str1 - *str2;
}

strncpy

        strncpy是长度受限制的字符串拷贝函数,可以指定要拷贝字符的个数,如果源字符串的长度小于要拷贝的个数,就在后边补\0,函数原型如下:

//destination是目标字符串地址,source是源字符串地址,num是要拷贝的字符个数,返回的是目标字符串地址
char * strncpy ( char * destination, const char * source, size_t num );
#include <stdio.h>
#include <string.h>
int main()
{
    // 代码1
    char arr[10] = "abcdef";
    char a[] = "hello";
    strncpy(arr, a, 3);
    printf("%s\n", arr);//会打印heldef,只拷贝了三个字符,后面的不变
     strncpy(arr, a, 5);
    printf("%s\n", arr);//会打印hellof,只拷贝了五个字符,没有拷贝到\0,后面的不变
     strncpy(arr, a, 6);
    printf("%s\n", arr);//会打印hello,拷贝到了\0
    return 0;
}

strncat

        strncat用于在目标字符串的结尾(第一个\0)处追加源字符串的前num个字符,并且会在后面加上一个\0,其函数原型如下:

//destination是目标字符串地址,source是源字符串地址,num是要追加的字符个数,返回的是目标字符串地址
char * strncat ( char * destination, const char * source, size_t num );

strncmp

        strncmp用来比较两个字符串的前num个字符,其函数原型如下:

//str1是第一个字符串的地址,str2是第二个字符串的地址,num是要比较的字符个数
//如果str1>str2,返回正数,反之返回负数,相等返回0
int strncmp ( const char * str1, const char * str2, size_t num );

strstr

        strstr用于在一个字符串中查找另一个字符串,其函数原型如下:

//在字符串str1中查找字符串str2的位置,如果找到了,返回str2在str1中的起始地址,没找到返回NULL
char * strstr ( const char *str1, const char * str2);
int main()
{
    char email[] = "abc@godfather.com";
    char str[] = "godfather";
    char* ret = strstr(email,str);
    if(ret == NULL)
        printf("未找到字符串\n");
    else
        printf("%s\n",ret);//在email中能找到str,ret会返回g的地址,会打印godfather.com
    return 0;
}

         下面来模拟实现一下strstr:

/*
 * @brief    在字符串str1中查找字符串str2
 * @param    str1:
 * @param    str2:
 * @return   char*: 返回str2在str1中的位置,如果没找到就返回NULL
 */
char *my_strstr(const char *str1, const char *str2)
{
    assert(str1 && str2);
    const char *s1 = str1;
    const char *s2 = str2;
    const char *ret = str1; // ret是str1中向后走的指针
    while (*ret)
    {
        s1 = ret;
        s2 = str2;
        while (*s1 && *s2 && (*s1 == *s2)) // 如果找到相等的字符就向后查找,如果遇到不相等或某个字符串遇到\0就退出循环
        {
            s1++;
            s2++;
        }
        if (*s2 == '\0') // 如果退出循环时s2遇到了\0,就说明找到了字符串,返回此时str1中的起始地址
        {
            return (char *)ret;
        }
        ret++; // 如果没找到就令str1的移动指针++,向后寻找
    }
    return NULL; // 如果遍历完还是没找到就返回NULL
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值