字符串_字符函数和字符串函数

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。

字符串常量适用于那些对它不做修改的字符串函数。

目录

1.函数介绍

1.1strlen

1.1.1strlen函数的模拟实现

1.2strcpy

1.2.1strcpy函数的模拟实现

1.3 strcat(字符串追加)

1.3.1strcat函数的模拟实现

1.4strcmp

1.4.1strcmp函数的模拟实现

1.5strncpy、strncat、strncmp的使用 

1.5.1strncat函数的模拟实现 

1.5.2strcpy函数的模拟实现 

1.5.3strcmp函数的模拟实现 

1.6strstr(查找子串的一个函数)

1.6.1strstr函数的模拟实现

1.7strtok(切割字符串)

1.8 strerror

1.函数介绍

1.1strlen

size_t strlen(const char* str);

注意:

字符串以'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数但不包括'\0'。 

参数指向的字符串必须要以'\0'结束。

函数的返回值为size_t,是无符号的。(size_t转为定义即unsigned int)

1.1.1strlen函数的模拟实现

#include<stdio.h>
//法一:计数器实现
int my_strlen(char* str)
{int count = 0;while (*str != '\0'){str++;count++;}return count;
}
//法二:递归实现
int my_strlen(char* str)
{if (*str)return 1 + my_strlen(str + 1);elsereturn 0;
}
//法三:指针-指针
int my_strlen(char* str)
{char* p = str;while (*str){str++;}return str - p;
}
int main()
{char arr[] = "abcdef";int len = my_strlen(arr);printf("%d\n", len);return 0;
}

1.2strcpy

char* strcpy(char* destination,char* source);

注意:

源字符串必须以'\0'结束。

会将源字符串中的'\0'拷贝到目标空间。

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

目标空间必须可变

1.2.1strcpy函数的模拟实现

#include<stdio.h>
char* my_strcpy(char* dest, char* stc)
{char* ret = dest;while (*stc!='\0'){*dest++ = *stc++;}*dest = *stc;return ret;
}
//实际上strcpy返回的是目标空间的起始地址,因为我们是把源字符串拷贝到目标空间里,目标空间发生变化
int main()
{char arr1[20] = { 0 };char arr2[] = "hello world";my_strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}

1.3 strcat(字符串追加)

char* strcat(char* destination,char*  source)

注意:

源字符串必须以'\0'结束。

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

目标空间必须可修改。

1.3.1strcat函数的模拟实现

#include<stdio.h>
char* my_strcat(char* dest, char* stc)
{char* ret = dest;//1.找到目标空间末尾的\0while (*dest != '\0'){dest++;}//2.拷贝字符串while (*dest++ = *stc++)//相当于strcpy函数{;}return ret;
}
int main()
{char arr[20] = "hello ";my_strcat(arr, "world");printf("%s\n", arr);return 0;
}

 尽量不要自己给自己追加,可能会导致程序崩溃,因为在找到末尾的\0时会覆盖掉,导致自己破坏了自己的内容,从而陷入死循环。

1.4strcmp

int strcmp(const char* str1,const char* str2)

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "zhangsan";char arr2[] = "zhangsan";int ret = strcmp(arr1, arr2);if (ret < 0)printf("<\n");else if (ret == 0)printf("==\n");elseprintf(">\n");return 0;
}

标准规定:第一个字符串大于第二个字符串,则返回大于0的数字;第一个字符串等于第二个字符串,则返回0;第一个字符串小于第二个字符串,则返回小于0的数字。

1.4.1strcmp函数的模拟实现

#include<stdio.h>
#include<string.h>
int my_strcmp(char* str1, char* str2)
{while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}return (*str1 - *str2);
}
int main()
{char arr1[] = "zhangsan";char arr2[] = "zhangsand";int ret = my_strcmp(arr1, arr2);if (ret < 0)printf("<\n");else if (ret == 0)printf("==\n");elseprintf(">\n");return 0;
}

1.5strncpy、strncat、strncmp的使用 

上面几个字符串函数不受长度限制,会有安全隐患。这里提供几个长度受限制的字符串函数:strncpy、strncat、strncmp,这三个函数和strcpy、strcat、strcmp使用方法基本一致,但其多了一个n,并且在调用函数时多了一个参数,其用来限制具体操作的字符个数。

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

char* strcpy(char* destination,char* source,size_t num) ;

char* strcmp(char* destination,char* source,size_t num) ;

我们拿strncat举例: 

#include<stdio.h>
int main()
{char arr1[20] = "abcdef";char arr2[] = "hello";strncat(arr1, arr2,3);printf("%s\n", arr1);return 0;
}

 1、将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加一个\0字符。

2、如果source指向的字符串的长度小于num的时候,只会将字符串中到\0的内容追加destination指向的的字符串末尾。

1.5.1strncat函数的模拟实现 

#include<stdio.h>
char* my_strncat(char* dest, char* stc, int num)
{char* p = dest;while (*dest){dest++;}while (*stc&&num--){*dest++ = *stc++;}*dest = '\0';return p;
}
int main()
{char arr1[20] = "abcdef";char arr2[] = "hello";my_strncat(arr1, arr2,3);printf("%s\n", arr1);return 0;
}

1.5.2strcpy函数的模拟实现 

#include<stdio.h>
char* my_strncpy(char* dest, char* stc, int num)
{char* p = dest;while (num--){*dest++ = *stc++;}return p;
}
int main()
{char arr1[20] = "abcdef";char arr2[] = "hello";my_strncpy(arr1, arr2,3);printf("%s\n", arr1);return 0;
}

1.5.3strcmp函数的模拟实现 

 

#include<stdio.h>
int my_strncmp(char* dest, char* stc, int num)
{while (num && dest && stc){if (*dest > *stc){return 1;}if (*dest < *stc){return -1;}num--;dest++;stc++;}return 0;
}
int main()
{char arr1[20] = "abcdef";char arr2[20] = "abcdeq";int ret=my_strncmp(arr1, arr2, 6);if (ret>0)printf(">\n");else if (ret<0)printf("<\n");elseprintf("==\n");return 0;
}

1.6strstr(查找子串的一个函数)

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

例子:

#include<stdio.h>

int main()
{
    char arr1[] = "abcdef";
    char arr2[] = "bcde";
    char* ret = strstr(arr1, arr2);//如果能找到,返回的是b的地址,找不到返回的是空指针
    if (ret == NULL)
        printf("找不到\n");
    else
        printf("%s\n",ret);
    return 0;
}

1.6.1strstr函数的模拟实现

#include<stdio.h>
char* my_strstr(const char* str1,const char* str2)//尽量不要让str1和str2乱动
{const char* s1 = str1;const char* s2 = str2;const char* p = str1;while (*p){s1 = p;s2 = str2;while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return p;p++;}return NULL;
}
int main()
{char arr1[] = "abbbcdef";char arr2[] = "bcde";char* ret = my_strstr(arr1, arr2);//如果能找到,返回的是b的地址,找不到返回的是空指针if (ret == NULL)printf("找不到\n");elseprintf("%s\n",ret);return 0;
}

1.7strtok(切割字符串)

char* strtok(char* str,char* sep);

sep参数是一个字符串,定义了用作分隔符的字符集合;

第一个参数指定一个字符串,它包含了0个或多个由sep字符串中一个或者多个分隔符的标记;

strtok函数找到str中的下一个标记,并将用\0结尾,返回一个指向这个标记的指针;

strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置;

strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记;

如果字符串中不存在更多的标记,则返回NULL指针。

#include<stdio.h>
int main()
{const char* sep = "@.";char data[] = "http@csdn.com";char cp[30] = { 0 };//因为strtok函数在找字符串时会把标记符改成\0,所以可以拷贝一个临时数组strcpy(cp, data);char* ret = strtok(cp, sep);printf("%s\n", ret);ret = strtok(NULL, sep);//这个空指针代表从保存好的位置不断向后找,是一种状态。printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);//这样写是比较挫的,换种写法char* ret = NULL;for (ret = strtok(cp, sep); ret != NULL; ret = strtok(NULL, sep)){printf("%s\n", ret);}return 0;
}

1.8 strerror

char* strerror(int errnum);

返回错误码,所对应的错误信息。

举个例子:

#include<stdio.h>
#include<errno.h>
#include<string.h>
int main()
{//errno-C语言设置的一个全局的错误码存放的变量FILE* pf = fopen("text.txt", "r");if (pf == NULL){printf("%s\n", strerror(errno));return 1;}return 0;
}

字符分类函数:

函数如果它的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格' ',换页'\f',换行'\n',回车'\r',制表符'\t'或者垂直制表符'\v'
isgigit十进制数字0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

 详情可参考cpulscpuls.com网站,上面有详细介绍

字符转换:

int tolower(int c);//转小写

int toupper(int c);//转大写

 

 

 

 

 

 

 

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

威纶通触摸屏下载项目文件后,文本都变成了框框的解决办法

威纶通触摸屏下载项目文件后,文本都变成了框框的解决办法 我们在用Easy builder pro编辑某些项目的情况下,编译没问题,为什么下载到触摸屏之后,文本都变成了框框了呢? 分析:: 不能正常显示文本的原因是字体文件缺失。 解决办法: 如下图所示,在Easy builder pro软件中,…

自定义注解

例如写一个注解PrintTime 如下&#xff1a; import java.lang.annotation.*;//下面的注解属于元注解 Target({ElementType.PARAMETER,ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Inherited Documented public interface PrintTime {/*** 注解的属性*/public S…

数据可视化的艺术:使用Matplotlib和Seaborn揭示数据故事

引言 数据可视化是数据分析中的关键一环&#xff0c;它帮助我们理解数据模式、趋势和异常。在Python中&#xff0c;Matplotlib和Seaborn是两个流行的数据可视化库&#xff0c;它们提供了丰富的图表和图形选项&#xff0c;使数据的可视化变得简单而强大。 Matplotlib&#xff…

三分钟快速上手SpringSecurity框架

导入依赖框架 web 框架(spring-boot-starter-web) <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> springSecurity 框架(spring-boot-starter-security) <de…

【Uniapp】图片修复对比组件

效果图 不废话&#xff0c;直接上源码&#xff01; 组件直接用 <template><viewclass"img-comparison-container":style"width: width rpx;height: height rpx"><view class"before-image" :style"width: x rpx&quo…

C++基础——继承(下)

一、继承与静态成员 基类定义了static 静态成员&#xff0c;则整个继承体系里面只有一个这样的成员。无论派生出多少个子 类&#xff0c;都只有一个 static 成员实例 。 class person { public:person(const char* name "lisi"):_name(name){} public:string _name;…

54.指针

目录 一.什么是指针&#xff1f; 二&#xff0e;定义一个指针变量 三&#xff0e;指针变量类型 四&#xff0e;取地址运算符& 五.取值运算符* 六.视频教程 一.什么是指针&#xff1f; 口语中的指针一般指指针变量&#xff0c;指针变量存放的是一个地址。普通变量存放…

TCP(1)

传输层的两大协议是TCP 和 UDP &#xff0c;他们在传输数据的时候起到了不可替代的作用。那么什么是TCP呢&#xff1f; 首先TCP是一个网络传输协议&#xff0c;这个协议保证了可靠的数据传输。TCP是面向字节流的&#xff0c;全双工的&#xff08;也就是通信双方互相发消息&…

shell脚本之sort,uniq,tr,cut,sphit,paste,ecal与正则表达式

sort命令 uniq命令 tr命令 cut命令 sphit命令 paste命令 ecal命令 正则表达式 sort命令 sort命令---以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序 比较原则是从首字符向后&#xff0c;依次按ASCII码值进行比较&#xff0c;最后将他们按升序…

Redis 源码安装和入门介绍

Linux下的redis源码安装 redis介绍 Redis 是一个开源&#xff08;BSD许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构&#xff0c;如 字符串&#xff08;strings&#xff09;&#xff0c;…

Leetcode - 周赛397

目录 一&#xff0c;3146. 两个字符串的排列差 二&#xff0c;3147. 从魔法师身上吸取的最大能量 三&#xff0c;3148. 矩阵中的最大得分 四&#xff0c;3149. 找出分数最低的排列 一&#xff0c;3146. 两个字符串的排列差 本题就是求同一个字符在两个字符串中的下标之差的…

Nacos+GateWay 搭建微服务架构

文章目录 1.当前项目架构分析1.请求多个模块的方式1.请求renren-fast模块开发环境生产环境 2.请求sunliving-commodity模块1.使用环境变量资源路径的方式2.开发环境 dev.env.js3.生产环境 prod.env.js 3.文件上传请求 sunliving-service模块1.请求后端接口&#xff08;开发环境…