目录
1.字符分类函数
C语言中有一系列的函数时专门用来做字符分类的,特就是一个字符属于什么类型的字符的。
这些字符都需要包含一个头文件 <ctype.h>,函数如下:
函数 | 如果它的参数符合系列条件就返回真 |
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 | 任何可打印字符,包括图形字符和空白字符 |
下面来示范一下部分字符分类函数的使用方法,示例如下:
题目:写一个代码,将字符串中的小写字母转大写字母,其他字符不变。
分析:1.需要遍历字符串,找到小写字母
2.将找到的小写字母转变为大写字母
转变的办法:大写字母在ASCII码表中的值比小写字母小32,所以可以使用小写字母减去32就能得到小写字母
2.字符转换函数
C语言提供了两个字符转换函数:
int tolower(int c); //将参数传递进去的小写字母转为大写字母
int tolupper(int c); //将参数传递进去的大写字母转为小写字母
在上面的题目中,在进行字母大小写转换时,我们使用的是ASCII码表值进行转换。这里有了转换函数,就可以使用函数进行转换了。
3.strlen函数的使用和模拟实现
3.1 strlen函数
strlen 函数的格式如下:
size_t strlen(const char* str);
- 字符串以 '\0' 作为结束标志,strlen 函数返回的是字符串中 '\0' 前面的字符个数(不包括 '\0')
- 参数指向的字符串必须要以 '\0' 结束
- strlen 函数的符号是 size_t ,是无符号的整型
下面来对一段代码进行判断,判断输出的是 > 还是 <=。代码如下:
int main()
{
const char* str1 = "abcdef123";
const char* str2 = "abc";
if (strlen(str2) - strlen(str1) > 0)
printf(" > \n");
else
printf(" <= \n");
return 0;
}
最后输出的结果为 > ,因为 strlen 函数返回的值是无符号整型(size_t),两个无符号整型相减得到的结果还是无符号整型,所以相减之后得到的值还是大于0的整型。
3.2 strlen 函数的模拟实现
方法一:遍历字符串,每遇到一个字符,count就+1,直到遇到 '\0' 。
#include <assert.h>
size_t my_strlen(const char* str)
{
size_t count = 0;
assert(str != NULL);
while (*str!='\0')
{
count++;
str++;
}
return count;
}
方法二:记住str在内存中的起始位置,然后遍历字符串,直到遇到 '\0',使用str最后的位置减去起始位置。
size_t my_strlen(const char* str)
{
char* start = str;
while (*str != '\0')
{
str++;
}
return str - start;
}
方法三:使用递归的思想,在没有遇到遇到 '\0' 之前,就计算一个字符数量并将 str 在内存的位置+1,直到遇到 '\0',返回0。
size_t my_strlen(const char* str)
{
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str+1);
}
4.strcpy函数的使用和模拟实现
4.1 strcpy 函数
strcpy函数的格式如下:
char* strcpy(char* destination, const char* source);
- 源字符串必须以 '\0' 结束
- 会将源字符串中的 '\0' 拷贝到目标空间
- 目标空间必须足够大,以确保能存放源字符串
- 目标空间必须可以修改
使用 strcpy 函数的示例如下:
4.2 strcpy 函数的模拟实现
版本1:遍历字符串,将sor中的字符复制到des中,最后将 '\0' 也复制进去。
void my_strcpy(char* des, char* sor)
{
while (*sor != '\0') //遍历字符串,直到遇到'\0'后退出循环
{
*des = *sor; //将sor中字符复制到des中
des++;
sor++;
}
*des = *sor; //将'\0'复制到des中
}
版本2:将复制的过程当做循环的条件,表达式的意思:先将sor中的字符复制到des中,然后再将des++和sor++。
void my_strcpy(char* des, char* sor)
{
while (*des++ = *sor++)
{
;
}
}
版本3:对函数调用的参数进行断言,提高代码的健壮性
#include <assert.h>
void my_strcpy(char* des, char* sor)
{
assert(des&&sor); //des 和 sor 需要同时为真
while (*des++ = *sor++)
{
;
}
}
版本4:des指向的空间是需要改变的,但是sor指向的空间不希望被改变
#include <assert.h>
void my_strcpy(char* des, const char* sor)
{
assert(des&&sor); //des 和 sor 需要同时为真
while (*des++ = *sor++)
{
;
}
}
版本5:能返回字符串的起始位置,能够进行链式访问。
#include <assert.h>
char* my_strcpy(char* des, const char* sor)
{
char* ret = des;
assert(des && sor);
while (*des++ = *sor++)
{
;
}
return ret;
}
int main()
{
char str1[] = "Hello";
char str2[10] = "abcd";
printf("%s\n", my_strcpy(str2, str1)); //链式访问
return 0;
}
5.strcat 函数的使用和模拟实现
5.1 strcat 函数
strcat 函数的格式如下:
char * strcat ( char * destination, const char * source );
- 源字符串必须以 '\0' 结束,否则没有办法知道从哪里结束追加
- 目标字符串中也得有 '\0' ,否则没有办法知道从哪里开始追加
- 目标空间必须有足够大,能容纳下源字符串的内容
- 目标空间必须可修改
使用 strcat 函数的示例如下:
5.2 strcat 函数的模拟实现
记录下des的起始位置,方便最后返回这个指针。
先在des中遍历数组找到 '\0',然后从这个位置开始追加字符串。
6.strcmp函数的使用和模拟实现
6.1 strcmp函数
strcmp 函数的格式如下:
int strcmp(const char* str1, const char* str2);
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
strcmp 函数的模拟实现:
6.2 strcmp 函数的模拟实现
当 s1 和 s2 相等时,会进入循环,如果 s1 的值为 '\0'时,那么 s2 值和 s1 一样,返回0表示相等。如果 s1 的值不为 '\0'时,就会地址+1,继续寻找不一样的值,找到这个位置时,就可以通过ASCII码值,将 s1 和 s2 位置的值相减。得到的是正数,就是 s1 大;得到的是负数,就是 s2 大。
#include <assert.h>
int my_strcmp(const char* s1, const char* s2)
{
assert(s1 && s2);
while (*s1 == *s2)
{
if (*s1 == '\0')
return 0;
s1++;
s2++;
}
return *s1 - *s2;
}
7.strncpy 函数的使用和模拟实现
7.1 strncpy 函数
strncpy 函数的格式如下:
char * strncpy ( char * destination, const char * source, size_t num );
其他的规则和 strcpy 函数的规则一致,不一致的规则如下 :
- 拷贝 num 个字符从源字符串到目标空间
- 如果源字符串的长度小于 num,则拷贝完源字符串之后,在目标的后边追加0,直到 num 个
strncpy 函数的使用示例如下:
7.2 strncpy 函数的模拟实现
和之前的 strcpy 函数的实现比较相似,只需要加上限制拷贝字符数量的条件即可。
#include <assert.h>
char* my_strncpy(char* des, const char* sor, const size_t num)
{
char* ret = des;
assert(des && sor);
for (int i = 1; i<=num; i++)
*des++ = *sor++;
return ret;
}
8.strncat 函数的使用和模拟实现
8.1 strncat 函数
strncat 函数的格式如下:
char * strncat ( char * destination, const char * source, size_t num );
strncat 函数的使用示例如下:
8.2 strncat 函数的模拟实现
strncat 函数的规则和 strcat 函数的规则一致,只需要加上限制链接字符数量的条件即可。
#include <assert.h>
char* my_strncat(char* des, const char* sor, const size_t num)
{
assert(des &&sor);
char* ret = des;
while (*des != '\0')
des++;
for (int i = 1; i <= num; i++)
*des++ = *sor++;
return ret;
}}
9.strncmp 函数的使用和模拟实现
9.1 strncmp 函数
strncmp 函数的格式如下:
int strncmp ( const char * str1, const char * str2, size_t num );
strncmp 函数的使用示例如下:
9.2 strncmp 函数的模拟实现
strncmp 函数的规则和 strcmp 函数的规则类似,只需要加上限制链接字符数量的条件即可。
#include <assert.h>
int my_strncmp(const char* s1, const char* s2, const size_t num)
{
assert(s1 && s2 && num);
for (int i = 1; i <= num && *s1 == *s2; i++)
{
if (*s1 == '\0')
return 0;
s1++;
s2++;
}
return *s1 - *s2;
}