目录
字符分类函数
函数讲解
使用样例
字符转换函数
函数讲解
使用样例
strlen的使用和模拟实现
strlen的使用
strlen的模拟实现
计数器
递归(不创建临时变量)
指针-指针
strcpy的使用和模拟实现
strcpy的使用
strcpy的模拟实现
strcat的使用和模拟实现
strcat的使用
strcat的模拟实现
strcmp的使用和模拟实现
strcmp的使用
strcmp的模拟实现
strstr的使用和模拟实现
strstr的使用
strstr的模拟实现
strncpy的使用和模拟实现
strncpy的使用
strncpy的模拟实现
strncat的使用和模拟实现
strncat的使用
strncat的模拟实现
strncmp的使用和模拟实现
strncmp的使用
strncmp的模拟实现
字符分类函数
函数 | 如果它的参数符合下列条件就返回真 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行'\n',回车'\r',制表符'\t',或垂直制表符'\v' |
isdigit | 十进制数字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 | 任何可打印字符,包括图像字符和空白字符 |
函数讲解
这些函数的使用方法都十分类似
int islower ( int c );
如果为假,函数会返回0,如果为真,函数会返回非零的值
iscntrl用来判断一个字符是否为控制字符
isspace用来判断一个字符是否为空白字符
isdigit用来判断字符或者字符串是否为数字
islower用来判断一个字符是否为小写字母
isupper用来判断一个字符是否为大写字母
isalpha用来判断一个字符是否为字母
isalnum用来判断一个字符是否为字母或者数字
ispunct用来判断一个字符是否为标点符号
isgraph用来判断一个字符是否为图形字符
isprint用来判断一个字符是否是可打印的
图形字符如下:
使用样例
#include <stdio.h>
#include <ctype.h>int main()
{int i = 0;char str[] = "Hello World\n";char c;while (str[i]){c = str[i];if (islower(c))c -= 32;putchar(c);i++;}return 0;
}
这里首先要包含头文件 ctype.h
然后使用了库函数 islower用来判断字符是否为小写字母
如果字符为小写字母则将字符减去32改成大写字母
所以这个程序的作用是将字符串中所有的小写字母改成大写字母
字符转换函数
C语言提供了2个字符转换函数
int tolower ( int c );
int toupper ( int c );
函数讲解
tolower可以将参数传进去的大写字母转小写
toupper可以将参数传进去的小写字母转大写
使用样例
#include <stdio.h>
#include <ctype.h>int main()
{int i = 0;char str[] = "Hello World\n";char c;while (str[i]){c = str[i];if (islower(c))c = toupper(c);putchar(c);i++;}return 0;
}
与上面近乎一致,只是将c -= 32变成了c = toupper(c)
两者的作用都相同,所以最终的结果也是一致的
strlen的使用和模拟实现
strlen的使用
该函数的作用是可以计算一个字符串的长度
也可以理解为计算'\0'之前出现的字符个数(不包含'\0')
这个长度最终以size_t函数的返回值形式出现(size_t为无符号整型)
我们只需要传一个字符串的起始地址给它即可(不一定是起始地址,从哪里传就从哪里开始计算)
#include <stdio.h>
#include <string.h>int main()
{char str[] = "Hello World";int ret = strlen(str);printf("%d\n", ret);return 0;
}
答案是由10个大小写字母和1个空白字符组成,所以答案是11
strlen的模拟实现
strlen的模拟实现有三种方法
计数器
#include <stdio.h>size_t my_strlen(const char* str)
{int count = 0;while (*str != '\0'){count++;str++;}return count;
}int main()
{char arr[] = "abcdefg";int ret = my_strlen(arr);printf("%d\n", ret);return 0;
}
注:如果有str为什么可以str++的问题可以看我前面的博客中的const修饰变量
C语言:指针的基础详解-CSDN博客
这里使用了1个变量count计数,随着str的增加count一同增加,直到碰到'\0'就停止即可
递归(不创建临时变量)
#include <stdio.h>size_t my_strlen(const char* str)
{if (*str == '\0')return 0;elsereturn 1 + my_strlen(str + 1);
}int main()
{char arr[] = "abcdefg";int ret = my_strlen(arr);printf("%d\n", ret);return 0;
}
这里使用递归逐渐增加str的位置,并且每递归一次就增加1,最终返回这个值即可
这个方法可以不需要创建临时变量
指针-指针
这里需要有一个知识点
两个同样类型的指针相减会得出它们之间元素的个数,以此得出第三个方法
#include <stdio.h>size_t my_strlen(const char* s)
{char* p = s;while (*p != '\0')p++;return p - s;
}int main()
{char arr[] = "abcdefg";int ret = my_strlen(arr);printf("%d\n", ret);return 0;
}
多创建一个指针变量p让它走到'\0'之前,最后指针-指针即可
strcpy的使用和模拟实现
strcpy的使用
该函数的作用是可以将一个字符串的内容拷贝到另一个字符串中,以需要拷贝的字符串中的'\0'作为标志结束
注意:目标空间必需要足够大且可修改,不然会越界
strcpy的模拟实现
#include <stdio.h>char* my_strcpy(char* dest, const char* src)
{char* ret = dest;while (*dest++ = *src++);return ret;
}int main()
{char arr1[] = "abcdefg";char arr2[20];my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}
这里的模拟实现先是创建了一个 char* ret用来保存原来目标字符串的起始地址(因为后面dest会改变),这样为后来的返回值做准备
这里直接简写成了用一个循环判断即可,当src为'\0'的时候赋值给dest自然就会停下循环
strcat的使用和模拟实现
strcat的使用
该函数的作用是可以把一个字符串连接到另一个字符串上面,也是以'\0'为标志结束
注意:目标空间必需要足够大且可修改,不然会越界
strcat的模拟实现
#include <stdio.h>char* my_strcat(char* dest, const char* src)
{char* ret = dest;while (*dest)dest++;while (*dest++ = *src++);return ret;
}int main()
{char arr1[20] = "Hello ";char arr2[] = "World";my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}
这里的模拟实现先是创建了一个 char* ret用来保存原来目标字符串的起始地址(因为后面dest会改变),这样为后来的返回值做准备
第一个循环的作用是找到dest的第一个'\0'
第二个循环即类似strcpy拷贝到末尾即可
最后返回起始dest的地址
strcmp的使用和模拟实现
strcmp的使用
该函数的作用是对两个字符串比较大小,从起始地址开始直到碰到'\0'结束一 一比较
如果直到结束两个字符都是相同的那么就说明字符串相等,则返回0
如果str1大于str2,返回大于0的数字,str1小于str2,返回小于0的数字(具体什么数字不做要求)
strcmp的模拟实现
#include <stdio.h>int my_strcmp(const char* str1, const char* str2)
{while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;
}int main()
{char arr1[10] = "abcde";char arr2[10] = "abq";int ret = my_strcmp(arr1, arr2);printf("%d", ret);return 0;
}
一个循环遍历两个字符串
如果走到'\0'则结束返回0
如果循环条件结束,则判断谁的ASCLL码值大,返回1或-1
strstr的使用和模拟实现
strstr的使用
该函数会在str1中寻找字符串str2
如果找不到则返回null
如果找到了会返回找到位置的起始地址
strstr的模拟实现
#include <stdio.h>char* my_strstr(const char* str1, const char* str2)
{char* ptr1 = str1;char* ptr2 = str2;char* cur = str1;while (*cur != '\0'){ptr1 = cur;ptr2 = str2;while (*ptr1 == *ptr2 && cur != '\0' && ptr2 != '\0'){ptr1++;ptr2++;}if (*ptr2 == '\0')return cur;cur++;}return NULL;
}int main()
{char arr1[20] = "hello@world.c";char arr2[20] = "llo";char* ret = my_strstr(arr1, arr2);printf("%s", ret);return 0;
}
这里需要定义几个char* 类型的变量来代替str1和str2移动
因为我们如果只有str1和str2就算能够找到str1中的str2也无法后退返回原来的地址了
例如:
如果我们从str1中找str2的时候,发现了第一个l,那么往后走发现第二个不是o的时候,我们如何返回呢?
str2判断完str1的ll不是lo的时候str2又怎么返回到str2的起始地址l中呢?
所以这就是需要定义多个char* 类型的变量来走的原因
第一个循环的cur是用来遍历的
第二个循环是用来判断字符串是否相同的
最后都返回找到的起始位置或者NULL即可
strncpy的使用和模拟实现
strncpy和strcpy的区别就差了一个n
这类型的函数有很多,都是加了一个n
这类函数会更加安全,因为strcpy拷贝的时候如果没有控制好数组的大小就会有越界的风险
所以strncpy的安全性会更高
strncpy的使用
strncpy可以自己选择需要拷贝多少个数据,我们只需要传参的时候多传一个num即可
这个num的单位是字节
strncpy的模拟实现
#include <stdio.h>char* my_strncpy(char* dest, const char* str, size_t num)
{char* ret = dest;int i = 0;for (int i = 0; i < num; i++){*(dest + i) = *(str + i);}return ret;
}int main()
{char arr1[] = "abcdefg";char arr2[20] = { 0 };my_strncpy(arr2, arr1 + 1, 5);printf("%s", arr2);return 0;
}
这里的实现和strcpy差不多
只不过用了个for循环来控制需要拷贝几个字符串即可
strncat的使用和模拟实现
strncat的使用
strcat是连接字符串
那么strncat就是可以决定需要连接几个字符串
strncat的模拟实现
#include <stdio.h>char* my_strncat(char* dest, char* str, size_t num)
{char* ret = dest;while (*dest != '\0'){dest++;}for (int i = 0; i < num; i++){*(dest++) = *(str++);}return ret;
}int main()
{char arr1[20] = "hello";char arr2[20] = " world";my_strncat(arr1, arr2 + 1, 3);printf("%s", arr1);return 0;
}
具体实现也和strcat差不多
for循环控制连接字符串个数
strncmp的使用和模拟实现
strncmp的使用
strcmp是比较两个字符串
strncmp是比较指定个数的两个字符串
其他的基本一致
strncmp的模拟实现
#include <stdio.h>int my_strncmp(const char* str1, const char* str2, size_t num)
{for (int i = 0; i < num; i++){if (*str1 > *str2)return 1;if (*str1 < *str2)return -1;str1++;str2++;}return 0;
}int main()
{char arr1[10] = "abcde";char arr2[10] = "abq";int ret = my_strncmp(arr1, arr2, 3);printf("%d", ret);return 0;
}
用for循环控制比较的字符个数
其他的与strcmp差不多一致
感谢观看
完