当前位置: 首页 > news >正文

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

目录

前言

一、strncpy函数

1.介绍

2.模拟实现:

二、使用步骤

 二、strncat函数

1.介绍

2.模拟实现:

 三、strncmp函数

1.介绍

2.模拟实现:

四、strstr函数

1.介绍

2.模拟实现:

函数 mystrstr 解析

功能:在 str1 中查找 str2,若找到返回子串起始地址,否则返回 NULL。

实现逻辑:

 五、strtok 函数

介绍

总结


前言

  在C语言字符函数和字符串函数(1)中,我们讲解了:

1. 字符分类函数
2. 字符转换函数
3. strlen的使用和模拟实现
4. strcpy的使用和模拟实现
5. strcat的使用和模拟实现
6. strcmp的使用和模拟实现

1~6的知识的相关内容,为上一章节知识的内容,本篇文章将讲解:
7. strncpy函数的使用
8. strncat函数的使用
9. strncmp函数的使用
10. strstr的使用和模拟实现
11. strtok函数的使用

7~11知识的相关内容,为本章节知识的内容。

一、strncpy函数

1.介绍

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

  strncpy函数strcpy函数功能相同,字符串拷⻉,即将代码中source的字符拷贝至 destination中,但strncpy函数多出了一个参数,新增的参数含义为最多拷贝num个字符。

即:

destination :指针,指向⽬的地空间(目的字符串)。

source :指针,指向源头数据(源头字符串)。

num :从source指向的字符串中最多拷⻉的字符个数。

返回值:strcpy 函数返回的⽬标空间的起始地址。

使用例:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
    char arr1[20] = { 0 };
    char arr2[] = "abcdefghi";
    char* str = strncpy(arr1, arr2, 5);
    printf("%s\n", arr1);
    printf("%s\n", str);
    return 0;
}

  strncpy函数strcpy函数功能相同,但也有区别的地方:

1.strcpy 函数拷⻉到\0 为⽌,如果⽬标空间不够的话,容易出现越界⾏为。
2.strncpy 函数指定了拷⻉的⻓度,源字符串不⼀定要有'\0', 同时在设计参数的时候,就会多⼀层思考:⽬标空间的⼤⼩是否够⽤。

注意:strncpy

  • 结束条件:复制 n 个字符  遇到source 的 '\0' 时停止(以先到者为准)。
  • 自动添加 '\0':否!仅当source  长度 < n 时,剩余部分用 '\0' 填充至 n 个字符;若 source 长度 ≥ n,则不添加 '\0'。注意strncpy 手动补 '\0'的情况

2.模拟实现:

  可用指针法:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
char* mystrncpy(char* a1, char* a2,int n)
{
    char* ret = a1;
    while ( n-- &&*a2)
    {
        *a1 = *a2;
        a1++, a2++;
    }
    while (n > 0)
    {
        a1++;
        *a1 = '\0';
        n--;
    }
    return ret;
}
int main()
{
    char arr1[20] = { 0 };
    char arr2[] = "abcdefghi";
    char* str = mystrncpy(arr1, arr2, 5);
    printf("%s\n", arr1);
    printf("%s\n", str);
    return 0;
}

  运行结果一样的。

二、使用步骤

 二、strncat函数

1.介绍

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

strncat函数strcat函数功能相同,功能:字符串追加,将源头字符串中的字符,即将代码中source的字符追加至 destination结尾,但最多追加num个字符。

destination :指针,指向⽬的地空间

source :指针,指向源头数据

num :从source指向的字符串中最多追加的字符个数。

返回值strncat 函数返回的⽬标空间的起始地址

  使用例:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world";
    char* str = strncat(arr1, arr2, 5);
    printf("%s\n", arr1);
    printf("%s\n", str);
}

  strncat函数strcat函数功能相同,但也有区别的地方:

1.strncat 多了⼀个参数,num;

2. strcat函数在追加的时候要将源字符串的所有内容,包含 \0 都追加过去,但是strncat 的num数指定了追加的⻓度,同时函数中源字符串中不⼀定要有‘\0’了,strncat函数更加灵活,也更加安全。

2.模拟实现:

  可用指针法:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
char* mystrncat(char* a1, char* a2,int num)
{
    char* p = a1;
    while (*a1)
    {
        a1++;
    }
    while (num--&&*a2)
    {
        *a1 = *a2;
        a1++;
        a2++;
    }
    *a1 = '\0';
    return p;
}
int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world";
    char* str = mystrncat(arr1, arr2, 5);
    printf("%s\n", arr1);
    printf("%s\n", str);
}

  运行结果一样的。

 三、strncmp函数

1.介绍

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

   strncmp函数strcmp函数功能相同,功能:用来比较str1 和str2 指向的字符串,从两个字符串的第⼀个字符开始⽐较,如果两个字符的ASCII码值相等,就比较下⼀个字符。直到遇到不相等的两个字符,或者字符串结束,但比较的字符对数要在num个字符以内。

str1 :指针,指向要⽐较的第⼀个字符串。

str2 :指针,指向要⽐较的第⼆个字符串。

num :最多⽐较的字符个数。

返回值:strncmp 函数返回的两个字符串比较的值。

返回值规定:

1.第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字。

2.第⼀个字符串等于第⼆个字符串,则返回0。

3.第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字。

4.如果到了num对且这num对字符均相等,则返回0,按相等来看。

  使用例:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abcqw";
    int ret1 = strncmp(arr1, arr2, 3);
    printf("%d\n", ret1);
    int ret2 = strncmp(arr1, arr2, 4);
    printf("%d\n", ret2);
    return 0;
}

  strncmp函数strcpy函数功能相同,但也有区别的地方:

关键区别
1.比较长度限制:

  strcmp:无长度限制,会一直比较到字符串结束(存在越界风险,若字符串未正确以'\0'结尾)。
  strncmp:通过第三个参数n明确限制比较的最大字符数,更安全,可避免因字符串未结束导致的无限比较。
2.返回值逻辑:

  两者返回值规则相同:
  若s1 < s2:返回负数(通常是ASCII差值)
  若s1 == s2:返回0
  若s1 > s2:返回正数(通常是ASCII差值)
  但 strncmp 的“相等”可能仅指前n个字符相等,而非整个字符串相等。

2.模拟实现:

  可用指针法:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int mystrncmp(char* a, char* b,int num)
{
    while (num&&*a == *b)
    {
        if (*a == '\0')
        {
            return 0;
        }
        a++;
        b++;
        num--;
    }
    if (num == 0)
    {
        return 0;
    }
    return *a - *b;
}
int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "abcqw";
    int ret1 = mystrncmp(arr1, arr2, 3);
    printf("%d\n", ret1);
    int ret2 = mystrncmp(arr1, arr2, 4);
    printf("%d\n", ret2);
    return 0;
}

  运行结果一样的。

四、strstr函数

1.介绍

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

1.介绍:strstr 函数,功能为查找 str2 指向的字符串在 str1 指向的字符串中第⼀次出现的位置。

2.简⽽⾔之:在⼀个字符串中查找⼦字符串。

3.strstr 的使⽤得包含 #include <string.h>头文件。

4.参数: str1 :指针,指向了被查找的字符串。

               str2 :指针,指向了要查找的字符串。

5.返回值:

• 如果str1指向的字符串中存在str2指向的字符串,那么返回第⼀次出现位置的指针。

• 如果str1指向的字符串中不存在str2指向的字符串,那么返回NULL。

使用例:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
    char str[] = "This is a simple string";
    char* p;
    p= strstr(str, "simple");
    if (p != NULL)
        printf("%s\n", p);
    else
        printf("查找的字符串不存在\n");
            return 0;
}

2.模拟实现:

  该函数的模拟实现较为复杂,需要建立三个指针,进行实现,分别为  1.指向被指向的字符串(被查找的字符串),该字符指针来代指该串、2.一个每次承接要查找的字符串的首地址,3.一个每次承接(1.)的指针的首地址。

  可能有些模糊,先看代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
char* mystrstr(char* str1,char* str2)
{
    char* s1 = str1;
    char* s2, * s3;
    while (*s1)
    {
        s2 = s1;
        s3 = str2;
        while (*s2 && *s3)
        {
            if ((*s2) != (*s3))
                break;
            s2++;
            s3++;
        }
        if (*s3 == '\0')
            return s1;
        s1++;
    }
    return NULL;
}
int main()
{
    char str[] = "This is a simple string";
    char* p;
    p= mystrstr(str, "simple");
    if (p != NULL)
        printf("%s\n", p);
    else
        printf("查找的字符串不存在\n");
            return 0;
}

函数 mystrstr 解析

功能:在 str1 中查找 str2,若找到返回子串起始地址,否则返回 NULL
实现逻辑
  1. 初始化指针

    • s1 指向 str1 的当前比较起始位置(从首字符开始)。
    • s2 和 s3 作为临时指针,分别用于遍历 str1 的子串和 str2 本身。
  2. 外层循环:遍历 str1 的每个字符(while (*s1)),作为子串匹配的起点。

  3. 内层循环:逐个字符比较 s1 起始的子串与 str2

    • 若 *s2 == *s3,则两者都后移一位(s2++s3++)。
    • 若不相等,跳出内层循环,s1 后移一位(尝试下一个起始位置)。
  4. 匹配成功条件:当 s3 遍历到 str2 的结束符 '\0'(即 *s3 == '\0'),说明 str2 已完全匹配,返回此时的 s1(子串起始地址)。

  5. 未找到情况:若 str1 遍历结束仍未匹配,返回 NULL

  这是对应实现的讲解,运行结果一样的。

 五、strtok 函数

介绍

char *strtok(char *str, const char *delim);

功能:

1.分割字符串:根据 delim 参数中指定的分隔符,将输⼊字符串 str 拆分成多个⼦字符串。

2.修改原始字符串: strtok 会直接在原始字符串中插⼊ '\0' 终⽌符,替换分隔符的位置,因 此原始字符串会被修改。

参数:

1. str :⾸次调⽤时传⼊待分割的字符串;后续调⽤传⼊NULL ,表⽰继续分割同⼀个字符串。

2. delim :包含所有可能分隔符的字符串(每个字符均视为独⽴的分隔符)。

返回值:

1.成功时返回指向当前⼦字符串的指针。

2.没有更多⼦字符串时返回NULL。

注意点:

使⽤步骤

1.⾸次调⽤:传⼊待分割字符串和分隔符。

2.后续调⽤:传⼊ NULL 和相同的分隔符,继续分割。

3.结束条件:当返回 NULL 时,表示分割完成。

  通过使用例,解释一下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
    char arr[] = "192.168.6.111";
    const char* sep = ".";
    const char* str = NULL;
    char  buf[30] = { 0 };
    strcpy(buf, arr); 
for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep))
        {
            printf("%s\n", str);
        }
    return 0;
}

 strcpy(buf, arr);  是将arr的值拷贝到buf中,

for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep))

这句意为:在buf串中寻找sep的串,声明时可知,sep的串: const char* sep = ".";

  • 首次调用:strtok(buf, sep),传入原始字符串 buf 和分隔符 sep,返回第一个子串地址。
  • 后续调用:strtok(NULL, sep),传入 NULL 表示继续处理上一次的字符串,返回下一个子串地址,直至返回 NULL(所有子串已拆分完毕)。

  但使用本函数时也有些需要注意的点:

1.破坏性操作: strtok 会直接修改原始字符串,将其中的分隔符替换为 '\0' 。如果需要保留原 字符串,应先拷⻉⼀份原串。

2.连续分隔符:多个连续的分隔符会被视为单个分隔符,不会返回空字符串。

3.空指针处理:如果输⼊的str为NULL且没有前序调⽤,⾏为未定义。


总结

  以上就是今天要讲的内容,本文简单介绍了:

7. strncpy函数的使用
8. strncat函数的使用
9. strncmp函数的使用
10. strstr的使用和模拟实现
11. strtok函数的使用

知识的相关内容,为本章节知识的内容,希望大家能喜欢我的文章,谢谢各位。


文章转载自:

http://XYc8BXYC.Lsmnn.cn
http://Gmmav0Jd.Lsmnn.cn
http://rLPG2oM5.Lsmnn.cn
http://3M4qagug.Lsmnn.cn
http://z2BOK2dc.Lsmnn.cn
http://ciHdeoFL.Lsmnn.cn
http://YLkZDjmA.Lsmnn.cn
http://x0SeQ23K.Lsmnn.cn
http://yxmFJuc3.Lsmnn.cn
http://cUFaJY0f.Lsmnn.cn
http://RS4yGKXC.Lsmnn.cn
http://RG9sduya.Lsmnn.cn
http://IluFcvkS.Lsmnn.cn
http://oL5oLPph.Lsmnn.cn
http://RwBgGq8g.Lsmnn.cn
http://sYF6Udk2.Lsmnn.cn
http://I2cDp1S7.Lsmnn.cn
http://2jQ7j7zy.Lsmnn.cn
http://tcSzmhl1.Lsmnn.cn
http://YMGUU9tK.Lsmnn.cn
http://wPvB59vU.Lsmnn.cn
http://t3e34Rjt.Lsmnn.cn
http://QiIDUXvZ.Lsmnn.cn
http://IwxY58Rf.Lsmnn.cn
http://0KLoubuW.Lsmnn.cn
http://Kl03RKvR.Lsmnn.cn
http://GdF7HSZr.Lsmnn.cn
http://a2mm6vlp.Lsmnn.cn
http://3zCainS2.Lsmnn.cn
http://BV3LVirV.Lsmnn.cn
http://www.dtcms.com/a/370791.html

相关文章:

  • 基于STM32的智慧民宿环境监测系统设计
  • 从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
  • [bat-cli] 打印机 | `src/printer.rs`
  • RLPR: EXTRAPOLATING RLVR TO GENERAL DOMAINS WITHOUT VERIFIERS
  • 抽成独立组件库:微前端架构下公共组件共享的最佳实践
  • 前端上传切片优化以及实现
  • 自适应滤波器:Ch1 正交性原理->维纳-霍夫方程
  • 1.5、机器学习-回归算法
  • 【基础-单选】UIAbility实例创建完成时触发的回调
  • 【YOLOv11】5.安装PyCharm
  • 从技术架构、接入路径、应用场景全梳理的智慧地产开源了
  • Javaweb 14.4 Vue3 视图渲染技术
  • 算法与数据结构实战技巧:从复杂度分析到数学优化
  • clang(clangd)与arm-linux-gcc、ARMGCC、ICCARM(IAR)、C51编译器的兼容性
  • 计算机视觉(八):开运算和闭运算
  • 工业显示器在地铁电力监控与运维中的应用
  • 集成学习 —— 梯度提升树GBDT、XGBoost
  • c++八股文1
  • CAD:注释
  • C++ 并发编程指南 并发设计模式:Actor vs. CSP (生活场景版)
  • LeetCode 468. 验证IP地址 - 详细解析
  • OpenLayers常用控件 -- 章节六:全屏控件教程
  • 7.网络虚拟化
  • 基于树莓派与Jetson Nano集群的实验边缘设备上视觉语言模型(VLMs)的性能评估与实践探索
  • AI工具深度测评与选型指南 - 文本生成与处理类
  • 【Proteus仿真】定时器控制系列仿真——LED小灯闪烁/流水灯/LED灯带控制/LED小灯实现二进制
  • 十三、计算机领域英语
  • 设计模式Design Patterns:组合Composite、命令Command、策略Strategy
  • 【Mysql-installer-community-8.0.26.0】Mysql 社区版(8.0.26.0) 在Window 系统的默认安装配置
  • 【STM32HAL-----NRF24L01】