C语言----字符函数和字符串函数(2)

简介: C语言----字符函数和字符串函数

C语言----字符函数和字符串函数(1)https://developer.aliyun.com/article/1544411

4.strcpy的使用和模拟实现

功能:拷贝字符串

strcpy---cpoy string

strcpy在拷贝的过程中会将arr1里面的内容包括\0拷贝到arr2里面去

int main()
{
    char arr1[] = "hello world";
    char arr2[20] = { 0 };
 
    //现在想把arr1里面的hello world放到arr2里面去
    //我们可以用strcpy来实现
    strcpy(arr2, arr1);
    printf("%s\n", arr2);
 
 
    return 0;
}

注意注意:

被拷贝的字符串一定要包含'\0',保证strcpy遇到\0就能停止拷贝

1.源头的字符串中必须包含\0,没有\0,strcpy是不能结束的

2.目标空间必须足够大,以确保能存放原字符串

3.目标空间必须是可以修改的

int main()
{
    char arr1[] = "hello world";
    char* p = "xxxxxxxxxxxxxx";//常量字符串--不能修改
 
    strcpy(p, arr1);//会报错的
    return 0;
}
//模拟实现拷贝
char*my_strcpy(char*dest,const char*src)//传过来的是首元素的地址,返回值是目标空间的起始地址,所以就是char*
{
    //*dest指向的是arr2第
    // 一个元素,*src指向的是arr1第一个元素
    //保证这两个指针不为空指针
    /*assert(src != NULL);
    assert(dest != NULL);*/
    //另一种写法:
    assert(dest && src);//如果dest为空指针,那么括号内就为0,就是假的,就会报错
 
    char* ret = dest;//将dest存起来
    while (*src != '\0')
    {
        *dest=*src;
        //进行加加操作,换下一个字符和下一个位置进行交换
        src++;
        dest++;
    }//当这个循环结束的时候,\0还没有被拷贝进去
    //最后的时候,src已经++成为\0了,那么现在再次赋值就能将\0拷贝进去了
    *dest =* src;//这里处理的就是\0
    return ret;//直接返回目标空间的起始地址
 
}
int main()
{
    char arr1[] = "abcdef";//末尾隐藏\0
    char arr2[20] = { 0 };
    //1.直接打印arr2
    my_strcpy(arr2, arr1);
    printf("%s\n", arr2);
 
 
    //2.接收返回值
    char* p = my_strcpy(arr2, arr1);
    printf("%s\n", p);
    //直接将返回值放到打印里面也可以
 
    printf("%s\n", my_strcpy(arr2, arr1));
    return 0;
}
 
 
//这个函数返回的是char*,为的是实现链式访问
 
//strcpy函数返回的是字符串拷贝成功过后,目标空间的起始地址,
//返回值就是arr2的首元素的地址
 
 
 
//总结:
//将arr1拷贝到arr2后,我们可以通过三种方法直接打印arr2
//一种就是直接打印arr2
//还有一种就是根据这个拷贝函数的返回值进行打印
//返回值是一个地址,在函数的一开始我们就将目标函数赋值给另一个临时指针,那么这个临时指针就指向了arr2
//在拷贝过后,我们直接将这个临时指针返回,所以在函数的开头我们用char*
//在返回了临时指针后,我们在主函数就用再创建一个临时指针变量进行返回值的接受,
//因为这个临时指针变量指向的是arr2的其实元素,那么我们就可以用这个临时指针变量直接打印arr2
//有了字符串起始元素的地址,我们就能打印这个字符串了
//对函数部分进行改进,
//思考:能不能将拷贝\0和前面的字符串放在一起呢?
 
char*my_strcpy(char*dest,const char*src)
{
 
    assert(dest && src);
 
    char* ret = dest;
    while (*dest++ = *src++)//因为这里是后置++,所以先带进去数据进行解引用,再进行++
    {
     //arr1里面的字符通过*dest++ = *src++这个代码一个个拷贝到arr2里面去了
      //在最后,*src是\0拷贝过去了,然后因为while循环里面是\0,所以循环停止了
      // 但是\0拷贝到dest里面了 
        ;
 
    }//这个循环拷贝过去之后判断表达式的值
    //因为是后置++,所以延后产生
 
    return ret;
 
}
 
int main()
{
    char arr1[] = "abcdef";
    char arr2[20] = { 0 };
 
    my_strcpy(arr2, arr1);
    printf("%s\n", arr2);
 
 
 
    char* p = my_strcpy(arr2, arr1);
    printf("%s\n", p);
 
 
    printf("%s\n", my_strcpy(arr2, arr1));
    return 0;
}

5.strcat的使用和模拟实现

原字符串必须有\0结尾

目标字符串也得有\0,否则没办法知道从哪里开始

目标空间必须足够大,能容纳下字符串的内容

目标空间是可以进行修改的,而不是常量不能进行修改

int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world";
 
    //如何将arr2里面的字符串追加在arr1后面呢?
    strcat(arr1, arr2);//字符串追加
    printf("%s\n", arr1);
    return 0;
}
 
//这个函数是如何实现追加呢?
//先找到目标函数的末尾\0的位置
//再将原字符串拷贝过来
 
//要求目标字符串末尾有\0,因为后面要将原字符串拷贝过去,所以原字符串也要有\0
//要返回目标空间的起始地址
//目标空间是可修改的,但是源头需要进行限制,不能被修改
char* my_strcat(char* dest,const char* src)//返回类型为char*类型的
//dest指向的是arr1的首元素的地址
//src指向的是arr2首元素的地址
{
    char* ret = dest;//将起始位置存起来
    assert(dest && src);//进行断言,防止空指针
    //1.找目标空间的\0
    while (*dest != '\0')
    {
        dest++;
    }//while循环找到\0就停下来
    //2.拷贝----我们在字符串追加的时候,我们要将目标字符串末尾的\0覆盖掉
    while (*dest++ = *src++)//这个代码是进行字符串间的拷贝的,因为上面已经找到\0了,已经停止循环了,并且dest指向了arr1末尾的\0
 
    {
        ;//写个分号就行了,循环得有一个循环语句
    }
 
    return ret;//直接返回arr1的起始地址
}
int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world";
 
    //如何将arr2里面的字符串追加在arr1后面呢?
    my_strcat(arr1, arr2);//字符串追加
    printf("%s\n", arr1);
    return 0;
}
 
//这个函数是如何实现追加呢?
//先找到目标函数的末尾\0的位置
//再将原字符串拷贝过来
 
//要求目标字符串末尾有\0,因为后面要将原字符串拷贝过去,所以原字符串也要有\0
 
 
 
//总结: 我们应该先找到目标字符串末尾\0的位置,这样我们才好追加,
//切记:追加的时候我们要将目标字符串末尾的\0覆盖掉
 
 
//在这个追加函数我们用了两个循环,第一个循环是找到\0,第二个循环是将原字符串拷贝到目标字符串的后面去

我们是不能对一个数组自己进行追加的

6.strcmp的使用和模拟实现

strcmp是用来比较两个字符串的

返回值是int

用返回值来比较这两个字符串大小

比较的是对应位置上的字符,如果对应位置字符相等就比较下一对字符

比较的不是字符串的长度,而是对应位置上字符的大小

如果两个字符串相等,返回值就是0

如果前面的字符串大于后面的字符串,那么就会返回一个大于0的数字

如果是后面的字符串大于前面的字符,前面的字符小,就返回一个小于 0的数字

int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abq";
    int ret=strcmp(arr1, arr2);
    //printf("%d\n", ret);//输出的结果是-1,就说明arr1<arr2
    if (ret == 1)//仅仅在vs平台可以写返回值为1,其他的平台就不知道返回值是多少了
    {
        printf(">" );
    }
    else
    {
        printf("<=");
    }
    return 0;
}
//
//int main()
//{
//    char arr1[] = "abcdef";
//    char arr2[] = "abq";
//    int ret=strcmp(arr1, arr2);
//    //printf("%d\n", ret);//输出的结果是-1,就说明arr1<arr2
//    if (ret == 1)//仅仅在vs平台可以写返回值为1,其他的平台就不知道返回值是多少了
//    {
//        printf(">" );
//    }
//    else
//    {
//        printf("<=");
//    }
//    return 0;
//}
 
 
//int my_strcmp(const char*str1,const char*str2)//返回值是Int,并且加上const进行限制
//{
//    //我们一对一对字符进行比较
//    assert(str1 && str2);
//    while (*str1 == *str2)
//    {
//        if (*str1 == '\0')//如果str1在上一轮循环++到\0之后,就说明这两个字符串已经完全相等了
//        {
//            return 0;//两个字符串完全相等
//        }
//        str1++;
//        str2++;
//    }//两个字符相等我们就找下一对字符进行比较
//    if (*str1 > *str2)
//    {
//        return 1;
//    }
//    else//*str1 < *str2
//    {
//        return -1;
//    }
//}
 
//另一种写法
int my_strcmp(const char* str1, const char* str2)//返回值是Int,并且加上const进行限制
{
    //我们一对一对字符进行比较
    assert(str1 && str2);
    while (*str1 == *str2)
    {
        if (*str1 == '\0')//如果str1在上一轮循环++到\0之后,就说明这两个字符串已经完全相等了
        {
            return 0;//两个字符串完全相等
        }
        str1++;
        str2++;
    }//两个字符相等我们就找下一对字符进行比较
    return (*str1 - *str2);//直接返回他们相减的值
 
}
int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abcdef";
    int ret=my_strcmp(arr1, arr2);
    printf("%d\n", ret);
    return 0;
}

C语言----字符函数和字符串函数(3)https://developer.aliyun.com/article/1544419

相关文章
|
15天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
15天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
18天前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。
|
18天前
|
存储 C语言
C语言程序设计核心详解 第七章 函数和预编译命令
本章介绍C语言中的函数定义与使用,以及预编译命令。主要内容包括函数的定义格式、调用方式和示例分析。C程序结构分为`main()`单框架或多子函数框架。函数不能嵌套定义但可互相调用。变量具有类型、作用范围和存储类别三种属性,其中作用范围分为局部和全局。预编译命令包括文件包含和宏定义,宏定义分为无参和带参两种形式。此外,还介绍了变量的存储类别及其特点。通过实例详细解析了函数调用过程及宏定义的应用。
|
18天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。
|
24天前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
24天前
|
C语言
C语言 字符串操作函数
本文档详细介绍了多个常用的字符串操作函数,包括 `strlen`、`strcpy`、`strncpy`、`strcat`、`strncat`、`strcmp`、`strncpy`、`sprintf`、`itoa`、`strchr`、`strspn`、`strcspn`、`strstr` 和 `strtok`。每个函数均提供了语法说明、参数解释、返回值描述及示例代码。此外,还给出了部分函数的自实现版本,帮助读者深入理解其工作原理。通过这些函数,可以轻松地进行字符串长度计算、复制、连接、比较等操作。
|
25天前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
1月前
|
C语言
【C语言】字符串及其函数速览
【C语言】字符串及其函数速览
25 4
|
1月前
|
机器学习/深度学习 编译器 Serverless
C语言中函数
C语言中函数
22 0