13、C语言中常见的字符串函数(strlen/strcpy/strcat/strcmp)

c语言中对字符和字符串的操作时非常频繁的,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串或者字符数组中。其中字符串常量适用于哪些对他不做修改的字符串函数

1. strlen

返回字符串长度,不包含\0

自己实现

int my_strlen(const char* str) // 因为只是求长度,并不改变内容,所以加上const
{
    int count = 0;
    assert(str != NULL); // 保证传入参数的有效性  使用需要引入assert.h头文件
    while(*str != '\0')
    {
        count++;
        str++;
    }
    return count;
}

但是C语言提供的strlen中,如果使用strlen("abc") - strlen("abcdef")结果竟然是>0

去库里查找这个函数,发现该函数的返回值类型是size_t而不是我们自己定义的int类型。size_t 其实是unsigned int类型,而-3转成无符号整形,是个正数

因此,需要注意strlen这个函数,不能直接加减运算,要先转成整形才可以!!!

2. strcpy

字符串拷贝函数,源字符串要以\0结尾,会把\0也拷贝到目标空间,目标空间要足够大,可以放下源字符串。

char arr1[] = "abcdef";
char arr2[] = "ggg";
strcpy(arr1, arr2); // \0也要拷贝过去,不然arr1就不是这个字符串了
// 只是把ggg\0替换了arr1中的abcd,后面的内容并不改变

模拟实现

// 返回值是char* 表示返回的是个地址,也就是拷贝之后的首地址  可以实现函数的链式访问
char* my_strcpy(char* destination, const char* source) // 原目标是不需要改变的,只改变目的目标
{
    assert(destination != NULL);
    assert(source != NULL);  // 指针不能为空的判断
    char* res = destination;
    while (*destination++ = *source++) {
        
    }
    return res;
}

所以

  • 没有\0会越界*destination++ = *source++
  • 目标空间足够大,不然是放不下的,也是越界访问
  • 目标空间必须可以改变,如果char* arr1 = "abcdef";,说明arr1指向的是常量字符串,是不能修改的,也是会出现错误

3. strcat

字符串追加函数。源字符串和目标空间要以\0结尾(不然不知道从哪里追加,追加到哪里),目标空间必须足够大,目标空间必须可以修改

字符串如何自己给自己追加?

strcat的使用

char arr1[] = "hello";
char arr2[] = "world";
strcat(arr1, arr2);   // 这样追加会越界,要保证 arr1的空间足够大
// 可以修改成 char arr1[20] = "hello";

模拟实现

char* my_strcat(char* dest, const char* sour)
{
    char* res = dest;
    assert(dest != NULL);
    assert(sour != NULL);
    while (*dest != '\0'){// 找到目的字符串的`\0`
		dest++;
	}
    while(*dest++ = *sour++){} // 追加
    return res;
}

所以:

  • 自己给自己追加的话,永远找不到\0,因为先找到目的字符串的\0,紧接着就是把源字符修改这个\0,就会导致往后循环永远找不到这个\0

4. strcmp

字符串比较函数

在这里插入图片描述

注意:使用 if (“abc” == “def”)这种比较方式是错误的,因为字符串常量用于表达式中,其实是首字母的地址,并不是这段内容

所以需要使用strcmp函数来进行字符串的比较

使用的注意点是不一定 str1 > str2就是1,只是在Windows下是1,所以记住是 > 0,而不一定是1

模拟实现1

int my_strcmp(const char* str1, const char* str2){
    assert(str1 != NULL);
    assert(str2 != NULL);
    while(*str1 && *str2)
    {
        if (*str1 == *str2)
        {
            str1++;
            str2++;
        }else{
            return *str1 - *str2;
        }
    }
    if (*str1) return 1;
    if (*str2) return -1;
    return 0;
}

模拟实现2

int my_strcmp(const char* str1, const char* str2){
    assert(str1 != NULL);
    assert(str2 != NULL);
    while(*str1 == *str2)
    {
        if (str1 == '\0')
        {
            return 0;
        }
        str1++;
        str2++;
    }
    if(*str1 > *str2)
    {
        return 1;
    }
    return -1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今儿背单词吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值