C语言:字符函数和字符串函数

server/2024/12/24 21:35:41/

一、字符分类函数

C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。
这些函数的使用都需要包含一个头文件是ctype.h
这些函数的使用方法非常类似,我们就讲解⼀个函数的事情,其他的非常类似:
int islower ( int c );
我们可以通过函数返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。
#include <stdio.h>
int my_islower(int n)
{if (n >= 97 && n <= 132)return 1;elsereturn 0;
}
int main()
{char a;while (scanf("%c", &a) != EOF){getchar();//取走多余的斜杠零if (my_islower(a))printf("小写字母\n");elseprintf("不是小写字母\n");}return 0;
}

那我们一般怎么去使用这个函数呢,接下来我们来看字符转换函数。

二、字符转换函数

C语言提供了2个字符转换函数:
int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写 
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

如果我们需要转变大小写字母,那么我们就要先去判断是大写字母还是小写字母,就会使用到刚才所说的字符分类函数。接下来我们来模拟一下这两个函数。

#include <stdio.h>
#include <ctype.h>
void my_tolower(char * str)
{while (*str){if (isupper(*str))*str += 32;putchar(*str);str++;}printf("\n");
}
void my_toupper(char* str)
{while (*str){if (islower(*str))*str -= 32;putchar(*str);str++;}printf("\n");
}
int main()
{char str1[5] = "AsdA";char str2[5] = "AsdA";my_tolower(str1);my_toupper(str2);return 0;
}

三、strlen的使用和模拟实现

size_t strlen ( const char * str );
字符串以 '\0' 作为结束标志,所以strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。 参数指向的字符串必须要以 '\0' 结束,不然结果就是随机的。还有需要注意的是函数的返回值为 size_t,是无符号的。我们在进行 strlen的使用时需要包含头文件string.h。
那我们来写一下strlen函数的模拟实现:
#include <stdio.h>
size_t my_strlen1(const char* str)
{size_t count = 0;while (*str){count++;str++;}return count;
}
size_t my_strlen2(const char* str)
{if (*str == '\0')return 0;elsereturn 1 + my_strlen2(str + 1);
}
size_t my_strlen3(const char* str)
{char* p = str;while (*p){p++;}return p - str;
}
int main()
{char str[6] = "sdawd";printf("%zd\n", my_strlen1(str));printf("%zd\n", my_strlen2(str));printf("%zd\n", my_strlen3(str));return 0;
}

四、strcpy的使用和模拟实现

char* strcpy(char * destination, const char * source );
strcpy的作用就是将源字符串拷贝到目标字符串。 源字符串必须以 '\0' 结束, 会将源字符串中的 '\0' 拷贝到目标空间。 目标空间必须足够大,以确保能存放源字符串
接下来我们来进行模拟实现:
#include <stdio.h>
char* my_strcpy(char* dest, const char* src)
{char* ret = dest;while (*src){*dest = *src;src++;dest++;}*dest = '\0';//while((*dest++ = *src++))//{//;//}return ret;
}
int main()
{char str[10];printf("%s\n", my_strcpy(str, "rgeaser"));return 0;
}

五、strcat的使用和模拟实现

strcat函数用于追加字符串。它接受两个字符串作为参数,把第二个字符串复制一份添加到第一个字符串的末尾。这个函数会改变第一个字符串,但是第二个字符串不变。 源字符串必须以 '\0' 结束。 目标字符串中也得有 \0 ,否则没办法知道追加从哪里开始。 目标空间必须有足够的大,能容纳下源字符串的内容。
那我们来模拟实现strcat吧。
#include <stdio.h>
char* my_strcat(char* dest, const char* src)
{char* ret = dest;while (*dest){dest++;}while ((*dest++ = *src++)){;}/*while (*src){*dest = *src;dest++;src++;}*dest = '\0';*/return ret;
}
int main()
{char str1[10] = "reg";char str2[10] = "fxg";printf("%s", my_strcat(str1, str2));return 0;
}
我们使用strcat时不能让字符串自己给自己追加,这是为什么呢? 目标字符串、 源字符串这两个字符串都必须是以 '\0' 结尾的。 当尝试让一个字符串追加自己时,例如使用  strcat(str, str) 在追加过程中源字符串会被修改,导致原来的结束符丢失。这样,目标字符串的结束符会一直寻找下去,直至内存溢出,因此这是不允许的。
六、strcmp   的使用和模拟实现
strcmp的作用就是比较字符串。
第⼀个字符串大于第⼆个字符串,则返回大于0的数字
第⼀个字符串等于第⼆个字符串,则返回0
第⼀个字符串小于第⼆个字符串,则返回小于0的数字
那么如何判断两个字符串? 比较两个字符串中对应位置上字符ASCII码值的大小。
那接下来我们来模拟实现一下。
#include <stdio.h>
int my_strcmp(const char* str1, const char* str2)
{while ((*str1 == *str2)&& *str1 != '\0'&& *str2 != '\0'){str1++;str2++;}return *str1 - *str2;
}
int main()
{char str1[10] = "reg";char str2[10] = "fxg";printf("%d", my_strcmp(str1, str2));return 0;
}

七、strncpy函数的使用

char * strncpy ( char * destination, const char * source, size_t num );
和strcpy函数相似,但是可以控制拷贝的字符数。 拷贝num个字符从源字符串到目标空间。如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
八、 strncat函数的使用
char * strncat ( char * destination, const char * source, size_t num );

和strcat函数相似,但是可以控制追加的字符数。将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符。如果source 指向的字符串的长度小于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾。

九、 strncmp函数的使用
int strncmp ( const char * str1, const char * str2, size_t num );
和strcmp函数相似,但是可以控制比较的字符数。 比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不一样,就提前结束,大的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0。
十、 strstr 的使用和模拟实现
char * strstr ( const char * str1, const char * str2);
函数返回字符串str2在字符串str1中第一次出现的位置。 字符串的比较匹配不包含 \0 字符,以 \0 作为结束标志。返回指向  str1 中第一次出现的  str2 的指针,如果  str2 不是  str1 的一部分,则返回 null 指针。
那么接下来我们来模拟实现一下。
#include <stdio.h>
char* my_strstr(const char* str1, const char* str2)
{char* p =(char*) str2;while (*str1){while ((*str1 != *str2)&& (*str1)){str1++;}if (!*str1)break;char* ret = (char*) str1;while (*str1 == *str2){str1++;str2++;if (!*str2)return ret;}str2 = p;str1 = ret + 1;}return NULL;
}
int main()
{char str1[] = "This is a simple string";char str2[] = "simple";printf("%s", my_strstr(str1, str2));return 0;
}
#include <stdio.h>
char* strstr(const char* str1, const char* str2)
{char* cp = (char*)str1;char* s1, * s2;while (*cp){s1 = cp;s2 = (char*)str2;while (*s1 && !(*s1 - *s2))s1++, s2++;if (!*s2)return(cp);cp++;}return(NULL);
}
int main()
{char str1[] = "This is a simple string";char str2[] = "simple";printf("%s", strstr(str1, str2));return 0;
}

十一、strtok函数的使用

char * strtok ( char * str, const char * sep);
sep参数指向一个字符串,定义了用作分隔符的字符集合。 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记,是我们需要操作的对象。 strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以被strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。) 在第一次调用时,该函数需要一个字符串作为  str  的参数,其第一个字符用作扫描标记的起始位置。在后续调用中,该函数需要一个 null 指针,并使用最后一个标记结束后的位置作为扫描的新起始位置。我们再来看一下strtok 函数的返回值,如果找到令牌,则为指向令牌开头的指针,否则,为  null 指针。当在正在扫描的字符串中到达字符串的末尾(即 null 字符)时,始终返回  null 指针。我们可以借助前面的返回值打印出分割的字符串,也可以借助后面的返回值进行判断来结束程序的进行。(具体代码如下)
#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "192.168.6.111";char* sep = ".";char* str = NULL;for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}

十二、strerror 函数的使用

char* strerror ( int errnum );
strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头文件中说明的,C语言程序启动的时候就会使用一个全局的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会将对应的错误码,存放在errno中,而一个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
我们也可以了解⼀下 perror 函数,perror 函数相当于⼀次将上述代码中的第10行完成了,直接将错误信息打印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。其实,perror 函数相当于printf再加上strerror 函数的作用。

http://www.ppmy.cn/server/152872.html

相关文章

蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)

一、工程模版创建流程 第一步 创建新项目 第二步 选择型号和管脚封装 第三步 RCC使能 外部时钟&#xff0c;高速外部时钟 第四步晶振时钟配置 由数据手册7.1可知外部晶振频率为24MHz 最后一项设置为80 按下回车他会自动配置时钟 第五步&#xff0c;如果不勾选可能程序只会…

Ai编程从零开始全栈开发一个后台管理系统之用户登录、权限控制、用户管理-前端部分(十二)

云风网 云风笔记 云风知识库 一、创建前端部分 1、vite初始化项目 npm create vitelatest admin-frontend – --template vue-ts 2、安装必要的依赖 npm install vue-router pinia axios element-plus element-plus/icons-vue安装完成后package.json如下&#xff1a; {&qu…

每日一题(4)

有一只蜗牛位于二维坐标系的原点(0,0)&#xff0c;在x轴上有n根平行于y轴的竹竿&#xff0c;它们底部的纵坐标为0&#xff0c;横坐标分别为x_1,x_2,\cdots,x_n。蜗牛想要从原点走到第n根竹竿的底部(x_n,0)。蜗牛在x轴上的移动速度是1单位每秒&#xff0c;在竹竿上向上爬的速度是…

leetcode----mysql

1251. 平均售价 - 力扣&#xff08;LeetCode&#xff09; 表&#xff1a;Prices ------------------------ | Column Name | Type | ------------------------ | product_id | int | | start_date | date | | end_date | date | | price |…

LightGBM分类算法在医疗数据挖掘中的深度探索与应用创新(上)

一、引言 1.1 医疗数据挖掘的重要性与挑战 在当今数字化医疗时代,医疗数据呈爆炸式增长,这些数据蕴含着丰富的信息,对医疗决策具有极为重要的意义。通过对医疗数据的深入挖掘,可以发现潜在的疾病模式、治疗效果关联以及患者的健康风险因素,从而为精准医疗、个性化治疗方…

python+opencv+棋盘格实现相机标定及相对位姿估计

pythonopencv棋盘格实现相机标定及相对位姿估计 引言1&#xff0c;使用相机采集含棋盘格图像14张2&#xff0c;进行相机标定&#xff08;1&#xff09;测试软件1标定结果&#xff08;内参及畸变系数&#xff09;&#xff08;2&#xff09;测试软件2标定结果&#xff08;内参及畸…

Android Framework 中的 AV/Camera 技术架构详解

Android Framework 中的 AV/Camera 技术架构详解 引言 Android 操作系统作为全球最流行的移动操作系统之一,其强大的多媒体处理能力是其成功的关键因素之一。其中,摄像头(Camera)模块是 Android 系统中最为核心的部分之一,负责处理图像和视频的捕获、处理和传输。本文将…

typora数学符号

typora数学符号 Typora 是一个支持 LaTeX 数学公式的优秀 Markdown 编辑器&#xff0c;可以直接编写数学公式并实时渲染。以下是如何在 Typora 中使用数学公式的详细指南&#xff1a; 1. 启用数学公式支持 默认情况下&#xff0c;Typora 支持 LaTeX 格式的数学公式&#xff0…