C 语言笔记:字符串处理函数

一、获取字符串长度函数

头文件:#include <string.h>
函数定义:size_t strlen(const char *s);
函数功能:
测字符指针 s 指向的字符串中字符的个数,不包括’\0’ 返回值:字符串中字符个数

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

int main()
{
    char s1[100] = "hello";
    printf("s1_len = %d\n", strlen(s1));
    printf("s1_size = %d\n", sizeof(s1));

    char s2[100] = "hel\0lo";
    printf("s2_len = %d\n", strlen(s2));
    printf("s2_size = %d\n", sizeof(s2));

    char *s3 = "hello";
    printf("s3_len = %d\n", strlen(s3));
    printf("s3_size = %d\n", sizeof(s3));

    return 0;
}

执行结果:

s1_len = 5
s1_size = 100
s2_len = 3
s2_size = 100
s3_len = 5
s3_size = 8

strlen() 在获取字符串长度时,遇到第一个 \0 结束,且这个 \0 不算做字符串长度中。
s3 是一个指针变量,在 64 位操作系统中占 8 字节。

二、字符串拷贝函数

头文件:#include <string.h>
函数的定义:char *strcpy(char *dest, const char *src);
函数的说明:
拷贝 src 指向的字符串到 dest 指针指向的内存中,\0 也会拷贝
函数的返回值:目的内存的地址

注意:在使用此函数的时候,必须保证 dest 指向的内存空间足够大,否则会出现内存污染。(前面比后面长)

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

int main()
{
    char s1[32] = "hello world";
    char s2[32] = "abcdefg";

    strcpy(s1, s2);
    printf("s1 = %s\n", s1);

    int i;
    for(i = 0;i < 32;i++)
    {
        printf("[%c] - %d\n", s1[i], s1[i]);
    }
    return 0;
}

执行结果:

s1 = abcdefg
[a] - 97
[b] - 98
[c] - 99
[d] - 100
[e] - 101
[f] - 102
[g] - 103
[] - 0
[r] - 114
[l] - 108
[d] - 100
[] - 0

...

[] - 0

[字符] - ASCII码值

char *strncpy(char *dest, const char *src, size_t n);
函数的说明:
将 src 指向的字符串前 n 个字节,拷贝到 dest 指向的内存中
返回值:目的内存的首地址
注意:
(1)strncpy 不拷贝 \0
(2)如果 n 大于 src 指向的字符串中的字符个数,则在 dest 后面填充 n - strlen(src)\0

三、字符串追加函数

1. strcat() 函数

头文件:#include <string.h>
函数定义:char *strcat(char *dest, const char *src);
函数功能:
strcat 函数追加 src 字符串到 dest 指向的字符串的后面。追加的时候会追加’\0’ 注意:保证 dest 指向的内存空间足够大。

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

int main()
{
    char s1[32] = "hello world";
    char s2[32] = "ABCDEF";

    strcat(s1, s2);

    printf("s1 = %s\n", s1);

    return 0;
}

执行结果:

s1 = hello worldABCDEF

strcat() 是从 s1 的 \0 位置开始追加,直到 s2 的第一个 \0 位置复制完结束。

2. strncat() 函数

char *strncat(char *dest, const char *src, size_t n);

这个函数接受三个参数:
dest:指向目标字符串的指针,即将源字符串连接到其末尾。
src:指向源字符串的指针,即要连接到目标字符串末尾的字符串。
n:要连接的 src 字符串的最大长度。

strncat() 函数会将源字符串 src 的前 n 个字符连接到目标字符串 dest 的末尾,然后在连接后的字符串末尾添加一个 null 字符,以表示字符串的结束。连接后的字符串 dest 将会被修改,并且返回指向 dest 的指针。

strncat() 函数与 strcat() 函数的区别:
strncat() 函数允许指定要连接的 src 字符串的最大长度 n,以防止 src 字符串长度超过 dest 字符串剩余空间而导致的缓冲区溢出。

四、字符串比较函数

1. strcmp() 函数

头文件:#include <string.h>
函数原型:int strcmp(const char *str1, const char *str2);
这个函数接受两个参数:
str1:指向第一个要比较的字符串的指针。
str2:指向第二个要比较的字符串的指针。
返回值:
strcmp() 函数将会按照字典顺序(ASCII 码顺序)比较两个字符串。
如果第一个字符串 str1 按照字典顺序排在第二个字符串 str2 之前,则返回一个负整数;
如果两个字符串相等,则返回 0;
如果第一个字符串 str1 按照字典顺序排在第二个字符串 str2 之后,则返回一个正整数。

例:

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

int main()
{
    char s1[] = "hello";
    char s2[] = "hella";

    int ret = strcmp(s1, s2);

    if(ret == 0)
    {
        printf("s1=s2\n");
    }
    else if(ret>0)
    {
        printf("s1>s2\n");
    }
    else
    {
        printf("s1<s2\n");
    }
    return 0;
}

执行结果

s1>s2

当把"hella"改成"w"后,执行结果为:

s1<s2

这是因为,strcmp() 函数是逐字符比较的,只要出现不一样的 ASCII 码值,就会返回

2. strncmp() 函数

头文件:#include <string.h>
函数原型:int strncmp(const char *str1, const char *str2, size_t n);
这个函数接受三个参数:
str1:指向第一个要比较的字符串的指针。
str2:指向第二个要比较的字符串的指针。
n:要比较的字符数量。
返回值:
strncmp() 函数将会按照字典顺序(ASCII 码顺序)比较两个字符串的前 n 个字符。
如果第一个字符串 str1 的前 n 个字符按照字典顺序排在第二个字符串 str2 的前 n 个字符之前,则返回一个负整数;
如果两个字符串的前 n 个字符相等,则返回 0;
如果第一个字符串 str1 的前 n 个字符按照字典顺序排在第二个字符串 str2 的前 n 个字符之后,则返回一个正整数。

例:

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

int main()
{
    char s1[] = "hello";
    char s2[] = "hella";

    int ret = strncmp(s1, s2, 4);

    if(ret == 0)
    {
        printf("s1=s2\n");
    }
    else if(ret>0)
    {
        printf("s1>s2\n");
    }
    else
    {
        printf("s1<s2\n");
    }
    return 0;
}

执行结果:

s1=s2

五、字符查找函数

1. strchr() 函数

头文件:#include <string.h>
函数原型:char *strchr(const char *str, int c);
这个函数接受两个参数:
str:指向要搜索的字符串的指针。
c:要查找的字符,以 ASCII 码的形式表示。
strchr() 函数会在字符串 str 中查找字符 c 第一次出现的位置,并返回一个指向该位置的指针。
返回值:
如果在字符串 str 中找到了字符 c,则返回指向该字符的指针;
如果在字符串 str 中未找到字符 c,则返回空指针 NULL。

例:

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

int main()
{
    char s[] = "he6llo wo6rld";
    char *ret = strchr(s, '6');

    if(ret == NULL)
    {
        printf("not found\n");
    }
    else
    {
        printf("found it, pos = %d\n", ret - s);
    }
    return 0;
}

执行结果:

found it, pos = 2

2. strrchr() 函数

strrchr()用于在字符串中查找指定字符的最后一次出现的位置。
头文件:#include <string.h>
函数原型:char *strrchr(const char *str, int c);
这个函数接受两个参数:
str:指向要搜索的字符串的指针。
c:要查找的字符,以 ASCII 码的形式表示。
strrchr() 函数会在字符串 str 中从后向前查找字符 c 最后一次出现的位置,并返回一个指向该位置的指针。
返回值:
如果在字符串 str 中找到了字符 c,则返回指向该字符的指针;
如果在字符串 str 中未找到字符 c,则返回空指针 NULL。

例:

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

int main()
{
    char s[] = "he6llo wo6rld";
    char *ret = strrchr(s, '6');

    if(ret == NULL)
    {
        printf("not found\n");
    }
    else
    {
        printf("found it, pos = %d\n", ret - s);
    }
    return 0;
}

执行结果:

found it, pos = 9

六、字符串匹配函数

strstr用于在字符串中查找指定子字符串的第一次出现的位置。
头文件:#include <string.h>
函数原型:char *strstr(const char *haystack, const char *needle);
这个函数接受两个参数:
haystack:指向要搜索的主字符串的指针。
needle:指向要搜索的子字符串的指针。
strstr() 函数会在主字符串 haystack 中查找子字符串 needle 的第一次出现的位置,并返回一个指向该位置的指针。
返回值:
如果在主字符串 haystack 中找到了子字符串 needle,则返回指向该子字符串的指针;
如果在主字符串 haystack 中未找到子字符串 needle,则返回空指针 NULL。

例:

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

int main()
{
    char s[] = "1234:5678:999:666";
    char *ret = strstr(s, "666");

    if(ret == NULL)
    {
        printf("没找到\n");
    }
    else
    {
        printf("找到了,在字符串的第%d个位置\n", ret - s);
    }
    return 0;
}

执行结果:

找到了,在字符串的第14个位置

七、字符串转换数值

atoi函数把字符串转换为 int 类型
头文件:#include <stdlib.h>
函数原型:int atoi(const char *nptr);\

int num;
num=atoi(123);

则 num 的值为 123

将字符串转换为 long 用 atol(const char *nptr);
将字符串转换为 double 用 atof(const char *nptr);

例:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char s1[] = "1949";
    int ret1 = atoi(s1);
    printf("s1 = %d\n", ret1);

    char s2[] = "3.1415926";
    double ret2 = atof(s2);
    printf("s2 = %lf\n", ret2);
    return 0;
}

执行结果:

s1 = 1949
s2 = 3.141593

八、字符串切割函数

头文件:#include <string.h>
函数原型:char *strtok(char *str, const char *delim);
这个函数接受两个参数:
str:指向要切割的字符串的指针,第一次调用时传入要切割的字符串,后续调用时传入 NULL 表示继续处理上一次剩余的字符串。
delim:包含分隔符的字符串,用来指定在哪些字符处切割字符串。切割结果不包含 delim
strtok() 函数会从字符串 str 中按照 delim 中指定的分隔符进行切割,并返回第一个标记(token)。在第一次调用时,它会返回字符串 str 中第一个标记的指针,并用 null 字符替换标记的结尾,以便后续调用时能够从上一个标记的后面继续切割。在后续的调用中,如果传入的 str 参数是 NULL,则会继续处理上一次剩余的字符串,并返回下一个标记的指针。

例:

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

int main()
{
    char s[] = "111:222222:3333:44444444:55";
    char *ret;

    //第一次切割
    ret = strtok(s, ":");
    printf("ret = %s\n", ret);

    //后面所有切割,都要将NULL传入strtok的第一个参数
    while((ret = strtok(NULL, ":")) != NULL)
    {
        printf("ret = %s\n", ret);
    }
    return 0;
}

执行结果:

ret = 111
ret = 222222
ret = 3333
ret = 44444444
ret = 55

九、格式化字符串操作函数

1. sprintf() 函数

用于将格式化的数据写入到字符串中

头文件:#include <string.h>
函数原型:int sprintf(char *str, const char *format, ...);

这个函数接受至少两个参数:
str:指向目标字符串的指针,用于存储格式化后的数据。
format:格式控制字符串,包含了格式化输出的规则,类似于 printf() 函数中的格式控制字符串。
可变参数:根据格式控制字符串中的格式化说明符,提供要格式化的数据。

2. sscanf() 函数

用于从字符串中读取格式化的数据

头文件:#include <stdio.h>\ 函数原型:int sscanf(const char *str, const char *format, …);`

这个函数接受至少两个参数:
str:指向包含要解析的字符串的指针。
format:格式控制字符串,包含了解析输入字符串的规则,类似于 scanf() 函数中的格式控制字符串。
可变参数:用于存储从字符串中解析得到的数据。

例:

#include <stdio.h>

void test1()
{
    char str[20];
    int a, b, c;

    sprintf(str, "%d:%d:%d", 2024, 5, 1);
    printf("str = %s\n", str);

    sscanf("2024:5:1", "%d:%d:%d", &a, &b, &c);
    printf("a = %d, b = %d, c = %d\n", a, b, c);
}

int main()
{
    test1();
    return 0;
}

执行函数:

str = 2024:5:1
a = 2024, b = 5, c = 1

sscanf()的高级用法

void test2()
{
    //1.跳过数据:用%*d或%*s
    char str1[20];
    sscanf("1234 5678", "%*d %s", str1);
    printf("%s\n", str1);

    //2.读取指定宽度的数据:%[width]s
    char str2[20];
    sscanf("12345678", "%4s", str2);
    printf("%s\n", str2);

    //3.支持集合操作
    //  %[a-z]表示匹配a到z中任意字符(尽可能多的匹配)
    //  %[aBc]匹配a、B、c中一员,贪婪性
    //  %[^aFc]匹配非a、F、c的任意字符,贪婪性
    //  %[^a-z]表示读取除a-z以外的所有字符
    char str3[20];
    sscanf("wr89gfhGKLw32", "%[a-z]", str3);
    printf("%s\n", str3);
}
int main()
{
    test2();
    return 0;
}

执行结果:

5678
1234
wr

十、const

1. 修饰全局变量,只读

只能使用不能修改
如果直接修改,那么编译直接报错
如果通过指针修改,那么程序异常结束

#include <stdio.h>

//1. const修饰全局变量
const int a = 100;
void test1()
{
    printf("a = %d", a);

    a = 666;//a只读,不能赋值直接修改
    printf("a = %d", a);

    int *p = &a;
    *p = 888;//也不能通过指针修改
    printf("a = %d", a);
}
int main()
{
    test1();
    return 0;
}

2. 修饰普通局部变量

不能直接通过变量名赋值修改,因为会编译报错,但可以通过地址修改

//2. const修饰普通局部变量
void test2()
{
    const int b = 100;
    printf("b = %d\n", b);

    // b = 666;//不能通过赋值直接修改
    // printf("b = %d\n", b);

    int *p = &b;
    *p = 888;
    printf("b = %d\n", b);
}
int main()
{
    test2();
    return 0;
}

执行结果:

b = 100
b = 888

3. 修饰指针变量

情况1:const修饰指针变量的类型
void test3()
{
    int c = 100;
    const int *p = &c;
    printf("*p = %d\n", *p);

    c = 666;
    printf("*p = %d\n", *p);

    *p = 777;
    printf("*p = %d\n", *p);

    int d = 888;
    p = &d;
    printf("*p = %d\n", *p);
}
int main()
{
    test3();
    return 0;
}

会报错:

说明不能通过指针修改地址里面的值

情况2:const修饰指针变量

const int *p = &c;改为int *const p = &c;

会报错:

说明无法修改指针变量里保存的地址

情况3:const既修饰类型又修饰变量

const int *p = &c;改为const int *const p = &c;

会同时报情况1和情况2的错误

说明只能通过变量名修改值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/590090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不坑盒子激活码免费领取

不坑盒子的一些新出来的大功能&#xff0c;都需要账号有Pro权限才能使用了。 关键是这些功能还很强大呢&#xff01;不用还不行&#xff01; 今天发现一个可以免费领不坑盒子Pro激活码的方法&#xff1a; 扫码进去后&#xff0c;就能看到激活码了&#xff1a; 复制激活码&…

基于alpha shapes的边缘点提取(matlab)

1、原理介绍 由Edelsbrunner H提出的alpha shapes算法是一种简单、有效的快速提取边界点算法。其克服了点云边界点形状影响的缺点&#xff0c;可快速准确提取边界点。如下图所示&#xff0c;对于任意形状的平面点云&#xff0c;若一个半径为a的圆&#xff0c;绕其进行滚动&…

基于Java+SpringBoot+Mybaties-plus+Vue+elememt+hadoop + redis 医院就诊系统 设计与实现

一.项目介绍 前端&#xff1a;患者注册 、登录、查看首页、医生排班、药品信息、预约挂号、就诊记录、电子病历、处方开药、我的收藏 后端分为&#xff1a; 医生登录&#xff1a;查看当前排班信息、查看患者的挂号情况、设置患者就诊记录、电子病历、给患者开药和个人信息维护 …

安装部署大语言模型 | 通义千问

下载安装 进入ollama的仓库下载 「 qwen 7b 」 libraryGet up and running with large language models.https://ollama.com/library查找阿里的 「 qwen 」 根据自己的电脑配置情况&#xff0c;选择合适的模型 总体来说&#xff0c;模型是越大&#xff0c;效果越好&#xff0c…

Jammy@Jetson Orin Nano - Tensorflow GPU版本安装

JammyJetson Orin Nano - Tensorflow GPU版本安装 1. 源由2. 问题2.1 Tensorflow跑以下示例代码的时候&#xff0c;发现jtop中6个CPU占用率都跑满了。2.2 Jetson Orin Nano运行Tensorflow示例结果不一致 3. 分析3.1 当前版本Tensorflow 2.16.13.2 GPU版本二进制安装3.3 GPU版本…

Nginx深度解析:核心特性、应用场景与全局、events、http等全面配置指南

Nginx是一款高性能的Web服务器与反向代理服务器软件&#xff0c;以其高并发处理能力、低内存消耗和反向代理负载均衡功能闻名。它通过事件驱动、异步非阻塞I/O模型&#xff0c;实现了极高的效率和稳定性&#xff0c;广泛应用于网站部署、API代理、静态资源服务及微服务架构中&a…

边沿JK触发器

边沿JK触发器 电路组成 & 逻辑符号 工作原理 Q n 1 D Q^{n1}D Qn1D J Q n ‾ K Q n ‾ \overline{\overline{JQ^n}KQ^n} JQn​KQn​ ( J Q n ) ( K ‾ Q n ‾ ) (JQ^n)(\overline{K}\overline{Q^n}) (JQn)(KQn​) J K ‾ J Q n ‾ K ‾ Q n Q n ‾ Q n J\over…

《HCIP-openEuler实验指导手册》1.6 Apache静态资源配置(目录访问)

知识点 常用用途&#xff1a; 软件仓库镜像及提供下载服务&#xff1a; 配置步骤 删除网站主目录中的文件&#xff08;本实验机目录为/home/source ip为192.168.12.137 端口为81&#xff09; cd /home/source rm -rf *在主目录中新建6个文件夹如下图 mkdir test{1..6}新建…

Eclipse 开创性地集成 Neon Stack,将 EVM 兼容性带到 SVM 网络

2024年5月2日&#xff0c;全球——在塑造区块链网络的战略联盟的过程中&#xff0c;Eclipse 通过集成 Neon EVM 核心团队开发的技术堆栈 Neon Stack&#xff0c;成为首个打破 EVM-SVM 兼容性障碍的生态。 Eclipse 旨在通过结合以太坊和 Solana 的最佳特性&#xff0c;来重构区…

SpringBoot-@Transactional注解失效

Transactional注解失效 Transactional失效场景 以下是一些常见导致Transactional注解失效的场景&#xff0c;配合相应的Java代码演示&#xff1a; 1、方法修饰符非公开&#xff08;非public&#xff09; Transactional注解失效的原因在于Spring事务管理器如何实现对事务的代…

LeetCode135:分发糖果

题目描述 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。 相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c;计算并返回需…

Java -- (part20)

一.Map集合 1.概述 双列集合的顶级接口 2.实现类 HashMap 特点: a.key唯一,value可重复->如果key重复了,会发生value覆盖 b.无序 c.无索引 d.线程不安全 e.可以存null键null值 数据结构: 哈希表 方法: LinkedHashMap 特点: a.key唯一,value可重复->如果ke…

动态规划-回文子串问题

文章目录 1. 回文子串&#xff08;647&#xff09;2. 最长回文子串&#xff08;5&#xff09;3. 分割回文串 IV&#xff08;1745&#xff09;4. 分割回文串 II&#xff08;132&#xff09;5. 最长回文子序列&#xff08;516&#xff09;6. 让字符串成为回文串的最少插入次数&am…

【千帆平台】使用AppBuilder三步手搓应用创建精准多轮对话agent之K12互动式练习题

欢迎来到《小5讲堂》 这是《千帆平台》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言创建应用应用头像应用名称应用描述角色指令能力扩展开场白 …

ImportError: DLL load failed while importing win32api: 找不到指定的模块

问题描述 在pip install pywin32后有概率出现import win32api 报错ImportError: DLL load failed while importing win32api: 找不到指定的模块。怎么解决&#xff0c;更新重装都不行。下面给出个人可行的解决方案。 解决方案&#xff1a; 1、打开cmd切换到环境的Scripts文件…

【Linux】常用命令大揭秘,轻松驾驭终端世界

常见命令大全 概念1.1&#xff1a;开源、闭源的区别1.2&#xff1a;应用场景 发行版XShell3.1&#xff1a;使用XShell登入主机3.2&#xff1a;普通用户的增加、删除3.3&#xff1a;查看账户的信息whoami指令who指令 文件和目录基本命令4.1&#xff1a;指令的周边知识文件路径Li…

基于Unity+Vue通信交互的WebGL项目实践

unity-webgl 是无法直接向vue项目进行通信的&#xff0c;需要一个中间者 jslib 文件 jslib当作中间者&#xff0c;unity与它通信&#xff0c;前端也与它通信&#xff0c;在此基础上三者之间进行了通信对接 看过很多例子&#xff1a;介绍的都不是很详细&#xff0c;不如自己写&…

大语言模型在人类层面预测未来的研究与应用

概述 这项研究将探讨语言模型&#xff08;LM&#xff09;能否预测未来事件。在这项研究中&#xff0c;将开发一个系统来自动收集信息、生成和汇总预测结果。将从一个竞争性预测平台收集有关问题的数据&#xff0c;以评估 LM 的预测能力。结果表明&#xff0c;LM 可以与具有竞争…

STL中常见的算法及其应用(一)

总述: 一、常见的遍历算法 1、for_each//遍历容器 函数原型: for_each(iterator beg, iterator end, _func); beg:开始迭代器; end:结束迭代器; _func:函数或者函数对象; 总结:for_each函数在STL中十分重要,需要熟练掌握 示例: std::for_each 是 C++ 标准…

C#语言入门

一、基础知识 1. 程序语言是什么 用于人和计算机进行交流&#xff0c;通过程序语言让计算机能够响应我们发出的指令 2. 开发环境 IDE&#xff0c;集成开发环境。它就是一类用于程序开发的软件&#xff0c;这一类软件一般包括了代码编辑、编译器、调试器、图形用户界面等等工…