常见的字符串函数(包含头文件string.h)和字符函数(1)

目录

一. strlen函数

1.strlen的定义

2.strlen的使用

3.strlen的模拟实现

二.  strcpy函数

1.strcpy的定义

2.strcpy的使用

3.strcpy的模拟实现

三. strcat函数

1.strcat的定义

2.strcat的使用

3.strcat的模拟实现

四. strcmp函数

1.strcmp的定义

2.strcmp的使用

3.strcmp的模拟实现

五. strncpy函数

1.strncpy的定义

2.strncpy的使用

3.strncpy的模拟实现

六. strncat函数

1.strncat的定义

2.strncat的使用

3.strncat的模拟实现

七. strncmp函数

1.strncmp的定义

2.strncmp的使用

3.strncmp的模拟实现


一. strlen函数

1.strlen的定义
size_t strlen( const char* str );

->1. strlen函数可以计算出字符串的实际长度(遇到结束符\0结束,不包含\0)

->2. 返回值size_t 就是无符号整型(int unsigned)

typedef 新旧命名,用法:typedef unsigned int size_t 即:unsigned int被size_t替换

->3. const char* str 需要计算字符串的首地址,const保护传过来的数据不被篡改

2.strlen的使用
#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = "abcdef";
    int len = strlen(arr);
    printf("%d", len);
    retunrn 0;
}

得出的len的值为:6(数组的长度)

使用strlen注意事项:

->1.字符串的地址必须以终止符'\0'结束

#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = {'a','b','c'};
    int len = strlen(arr);
    retunrn 0;
}

因为strlen测量字符串是到'\0'结束,由于字符串中没有结束符'\0',strlen找不到结束计算的标志,就会一直向后寻找结束符'\0',直到找到'\0'为止,在此期间的所以我们不知道strlen函数遇到了多少字符,所以arr数组的长度是不可预知的,即arr的数组的长度是一个随机值

3.strlen的模拟实现

assert函数的作用:判断该地址是不是有效地址

模拟实现strlen有三种方法:

->1. 计数器

#include <stdio.h>
#include <assert.h>

int My_strlen(const char* str)
{
    assert(str);
    int count = 0;
    while(*str++)
    {
          count++;
    }
    return count;
}

->2. 指针 - 指针

#include <stdio.h>
#include <assert.h>

int My_strlen(const char* str)
{
    assert(str);
    char* det = str;
    while(*str++)
    {
          ;
    }
    return str - det;
}

->3. 递归

#include <stdio.h>
#include <assert.h>

int My_strlen(const char* str)
{
    assert(str);         
    if(*str == '\0')
       return 0;
    else
       return 1 + My_strlen(str + 1);
}

二.  strcpy函数

1.strcpy的定义
char *strcpy( char *Destination, const char *Source );

->1. 拷贝字符串(Source)放入目标空间(Destination)中

->2. char *Destination --- 目标空间的首地址

->3. const char *Source --- 源字符串的首地址,加上const保护字符串再操作过程中不被篡改

->4. 返回值为:操作完成后,返回终点目地的首地址

2.strcpy的使用
#include <stdio.h>
#include <string.h>

int main()
{
    char name[20] = {0};
    strcpy(name, "abcdef");  
    printf("%s", name);  
    return 0;
}

运行结果:

使用strcpy注意事项:

例1:

#include <stdio.h>
#include <string.h>

int main()
{
    char name[20] = {0};
    strcpy(name, "zhangsan");
    printf("%s", name);
    return 0;
}

运行结果:

strcpy函数拷贝到'\0'结束,它会将‘\0’之前的字符拷贝到name中包括'\0',用strcpy时,原数据需要'\0',不然没法停止

例2:

#include <stdio.h>
#include <string.h>

int main()
{
    char name[3] = {0};
    strcpy(name, "zhang");
    printf("%s", name);
    return 0;    
}

运行结果:

目标空间(name数组)太小装不下源字符串,程序会崩溃,但是内容还是会拷贝过去

例3:

#incldue <stdio.h>
#include <string.h>

int main()
{
    char* p = "abcdef";
    char str[] = "bit";
    strcpy(p, arr);
    return 0;
}

运行结果:

目标空间必须是可变的,不然程序就会崩溃,存放常量字符串的字符指针变量p的空间是不可变的

例4:

#include <stdio.h>
#include <string.h>

int main()
{
    char name[20] = "##################";
    strcpy(name, "zhangsan");
    printf("%s", name);
    return 0;
}

运行结果:

可以看到strcpy函数拷贝字符串时源字符串中的'\0'也会被拷贝进目标空间

总结:

->1. 源字符串必须以‘\0’结束

->2. 会将源字符串中的'\0'拷贝目标空间

->3. 目标空间必须足够大,以确保能存放源字符串

->4. 目标空间必须可变

3.strcpy的模拟实现
#include <stdio.h>
#include <string.h>

char* My_strcpy(char* str1, const char* str2)
{
    assert(str1&&str2);
    char* det = str1;
    while(*str++ = *str2++)
    {
          ;  //因为只有一条语句所以外面这对大括号可以省略
    }
    return det;
}

三. strcat函数

1.strcat的定义
char* strcat(char* Destination, const char* Source);

->1. 将字符串(Source)连接到目标空间(Destination)上

->2. char *Destination --- 目标空间的首地址

->3. const char *Source --- 源字符串的首地址,加上const保护字符串再操作过程中不被篡改

->4. 返回值为:操作完成后,返回终点目地的首地址

2.strcat的使用
#include <stdio.h>
#include <string.h>

int main()
{
    char str[20] = "hello ";
    strcat(str, "world");
    printf("%s", str);
    return 0;
}

运行结果:

strcat使用注意事项:

例1:

#include <stdio.h>
#include <string.h>

int main()
{
    char str[20] = "hel\0lo ";
    strcat(str, "world");
    printf("%s", str);
    return 0;
}

字符在使用strcat连接时,原字符串会连接在目标空间第一个出现'\0'的地方覆盖掉'\0'之后向后连接,原字符中必须的有终止符'\0',不然strcat函数会一直向后连接直到遇到'\0'

总结:

->1.目标空间需要足够大,能装下连接之后的新字符串

->2.与strcpy一样目标空间必须是可变的

->3.源字符串中的有'\0'

3.strcat的模拟实现
#include <assert.h>
#include <stdio.h>
char* My_strcat(char* det, const char* src)
{
    assert(det&&src);
    char* start = det;
    while(*det)
    {
          det++;
    }
    while(*det++ = *src++)
    {
          ;
    }
    return start;
}

注意:

不可自己跟自己追加:My_strcat(str, str)

会将'\0'覆盖掉,没有'\0'程序会陷入死循环

例:

四. strcmp函数

1.strcmp的定义
int strcmp( const char *string1, const char *string2 );

->1. 比较字符串的大小

->2. 放入需要比较大小的两个字符串的首地址到strcmp函数中

->3. 如str1大于str2就放回正整数,相等返回零,反之返回负整数

2.strcmp的使用
#include <stdio.h>
#include <string.h>

int main()
{
    char str1[20] = "zhangsan";
    char str2[20] = "zhangsanfeng";
    int ret = strcmp(str1, str2);
    if(ret > 0)
    printf("str1 > str2");
    else if(ret == 0)
    printf("str1 == str2");
    else
    printf("str1 < str2");
    return 0;
}
3.strcmp的模拟实现
#include <stdio.h>
#include <assert.h>

int My_strcmp(const char* str1, const char* str2)
{
    while(*str1 == *str2)
    {
          if(*str1 == '\0')
             return 0;
          str1++;
          str2++;
    }
    return (*str1 - *str2);
}

以上是长度不受限制的字符串函数

下面介绍长度受限制的字符串函数(于上面的字符串函数而言这种字符串函数的相对比较安全,且作用都是一样)

五. strncpy函数

1.strncpy的定义
char *strncpy( char *Destination, const char *Source, size_t count );

相比较strcpy而言功能一样,只是多了一个参数:size_t count  来控制拷贝个数

2.strncpy的使用

将str2的前五个字符复制到str1上

#include <stdio.h>
#incldue <string.h>

int main()
{
    char str1[20] = "abcdefg";
    char str2[20] = "holle world";
    strncpy(str1, str2, 5);
    printf("%s", str1);
    return 0;
}

运行结果:

例1:

拷贝的个数如果够就拷贝过去,不够就补'\0'

#include <stdio.h>
#incldue <string.h>

int main()
{
    char str1[20] = "abcdefg";
    char str2[20] = "mfn";
    strncpy(str1, str2, 5);
    printf("%s", str1);
    return 0;
}

运行结果:

3.strncpy的模拟实现
#include <stdio.h>
#include <assert.h>

char* My_strncpy(char* det, const char* src, int count)
{
    assert(det && src);
    char* start = det;
    while ((*det++ = *src++) && count--)
    {
           ;
    }
    if (count)
    {
        while (count--)
        {
            *det++ = '\0';
        }
    }
    return start;
}

int main()
{
    char str1[20] = "abcdefg";
    const char str2[20] = "mfn";
    printf("%s", My_strncpy(str1, str2, 5));
    return 0;
}

六. strncat函数

1.strncat的定义
char *strncat( char *Destination, const char *Source, size_t count );

相比较strcat而言功能一致,多了一个参数:size_t count  来控制连接个数

2.strncat的使用

将str2的三个字符连接到str1后面

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[20] = "hello\0xxx";
    char str2[20] = "wor";
    strncat(str1, str2, 3);
    printf("%s", str1);
    return 0;
}

运行结果:

在结尾会补'\0'作结束处理

将3改为6结果还是一样不会多补'\0'

3.strncat的模拟实现

#include <stdio.h>
#include <assert.h>

char* My_strncat(char* det, const char* src, int count)
{
    assert(det && src);
    char* start = det;
    while (*det)
    {
           det++;
    }
    while ((*det++ = *src++) && count--)
    {
           ;
    }
    if (!count)
    {
        *++det = '\0';
    }
    return start;
}

int main()
{
    char str1[20] = "hello\0xxx";
    char str2[20] = "wor";
    printf("%s", My_strncat(str1, str2, 6));
    return 0;
}

七. strncmp函数

1.strncmp的定义
int strncmp( const char *string1, const char *string2, size_t count );

相比较strcmp而言功能相同,多了一个参数:size_t count 来控制比较个数

2.strncmp的使用

比较str1和str2的前三个字符的大小

#include <stdio.h>
#include <string.h>

int main()
{
    char str1[] = "abcdef";
    char str2[] = "abc";
    int ret = strncmp(str1, str2, 3);
    if(ret > 0)
    printf("str1 > str2");
    else if(ret == 0)
    printf("str1 == str2");
    else
    printf("str1 < str2");
    return 0;
}

运行结果:

3.strncmp的模拟实现
#include <stdio.h>
#include <assert.h>

int My_strncmp(const char* str1, const char* str2, int count)
{
    assert(str1&&str2);
    while ((*str1 == *str2) && --count)
    {
        if (*str1 == '\0')
            return 0;
        str1++;
        str2++;
    }
    return (*str1 - *str2);
}
int main()
{
    char str1[] = "abcdef";
    char str2[] = "abc";
    int ret = My_strncmp(str1, str2, 3);
    if (ret > 0)
        printf("str1 > str2");
    else if (ret == 0)
        printf("str1 == str2");
    else
        printf("str1 < str2");
    return 0;
}

建议使用带n的版本,比较严谨一些

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值