一, 字符分类函数
C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h
1,iscntrl函数
原型:
int iscntrl(int c );
这里的参数int c可以理解为对应字符的ASCII码值。
功能:检查参数c是否为需要一个控制字符(ASCII码值在0~31之间的,包括DEL字符)
附:ASCII码值表
返回值:如果是控制字符,返回值不为0,否则返回值为0.
实操:
2,isspace函数
原型:
int isspace(int c);
功能:检查参数c是否为空白字符(空白字符的定义如上图所示)
返回值:如果c是空白字符,则返回值不为0,否则为0;
实操:
3,isdigit函数
原型:
int isdigit(int c);
功能:检查参数c是否为十进制数字(0,1,2,3,4,5,6,7,8,9)
返回值:如果是,返回值不为0,否则为0。
4,isxdigit函数
原型:
int isxdigit(int c);
功能:检查参数c是否为十六进制数字字符(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,A,B,C,D,E,F)
返回值:如果参数c是十六进制数字,则该返回值不为0,否则为0.
实操:
5,islower函数
原型:
int islower(int c);
功能:检查参数c是否为小写字母。
返回值:如果参数c是小写字母,则该返回值不为0,否则为0。
6,isupper函数
与islower同理。
7,isalpha函数
原型:
int isalpha(int c);
功能:检查参数c是否为字母(a~z,A~Z)
返回值:如果c确实是字母,则返回值不为0,否则为0 。
实操:
8,isalnum函数
原型:
int isalnum(int c);
功能:检查参数c是否为十进制数字还是大写或者小写字母。
返回值:如果c确实是数字或者字母,则该返回值不为0,否则为0.
实操:
9,ispunct函数
原型:
int ispunct(int c);
功能:检查参数c是否为一个符号(问号,逗号等)。
返回值:如果参数c是一个符号,则返回非0值,否则返回0。
实操:
10,isgraph函数
原型:
int isgraph(int c);
功能:检查字符是否有图形表示(除空格字符以外所有可以打印的字符)
返回值:如果c具有字符的图形表示,则该值不为0,否则该值为0。
实操:
11,isprint函数
原型:
int isprint(int c);
功能:检查字符c是否为可打印的字符(在显示器上占据显示位置的字符)
返回值:如果c确实是可打印的字符,则返回值不为0,否则为0。
实操:
练习:将字符串中的代码大写转小写
思路1:利用字母大写ASCII码值=小写字母ASCII码值-32.
优化:当一个字符串中既有大写字母又有小写字母时,可以借用字符分类函数进行优化。
思路2:借用字符转换函数。
二,字符转换函数
1,tolower函数
原型:
int tolower(int c);
功能:将参数c由大写字母转换为小写字母
返回值:大写字母返回对应的小写字母,小写字母不做更改返回。
2,toupper函数
原型:
int toupper(int c);
功能:将小写字母转换为大写字母
返回值:大写字母不做更改返回,小写字母返回对应的小写字母
3,大写转小写字符串的优化
三,strlen函数
原型:
size_t strlen(const char*c);
注意:• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包'\0') 。
• 参数指向的字符串必须要以 '\0' 结束。
• 注意函数的返回值为size_t,是⽆符号的(易错)
补充:size_t类型
size_t类型 无符号数整数类型
1,与编译器相关的无符号整数的c/c++类型
2,类型大小可选择,通常下足以保证存储内存中对象的大小 在不同平台和编译器下下大小可以不同
3,用于数组索引,在循环中遍历数组或者容器的元素,可以保证足够大以表示数组的索引范围,从而避免溢出问题
4,用于内存分配,表示内存分配的大小,有助于确保分配足够的内存以容纳数据
• strlen的使⽤需要包含头⽂件<string.h>
实操:
模拟实现:
1,计数器方式
int my_strlen(const char * str)
{
int count = 0;//借用临时变量count来纪录循环次数,当做字符串长度
assert(str);
while(*str)//当字符串为0是终止循环
{
count++;
str++;
}
return count;
}
2,递归法
int my_strlen(const char * str)
{
assert(str);
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);//借用函数递归实现,最后返回值即为字符串长度
}
3,指针法
int my_strlen(char *s)
{
assert(str);
char *p = s;//借用p存放字符串首元素地址
while(*p != '\0' )
p++;
return p-s;//通过指针-指针计算字符串长度
}
补充:指针-指针计算的是两个指针之间的距离(可正可负) 两个指针必须都指向同一块连续的空间。
四,strcpy函数
原型:
char* strcpy(char* destination, const char* source);
功能:将source的字符串复制到destination中
注意:
返回值:返回destination字符串首元素的地址
实操:
模拟实现:
思路:采用循环将字符串逐一拷贝直到拷贝完源头字符串的结束标志'\0"为止
注意事项:
1因为最后需要返回目的地的起始地址,因此拷贝前应当提点记录下目的地起始位置的指针
2,因为无论源地址为NULL,还是目的地地址为NULL,在后续函数的运行过程中都会导致指针的越界访问,因此我们选择在函数一开始就加入assert断言,防止传入空指针情况的出现
3,我们循环终止的条件是(源字符串不等于'\\0'),这意味着当函数拷贝到'\\0'字符时就会停止拷贝,结束运行,这会导致'\\0'并没有被拷贝到目的地中,后续可能会导致出现一些Bug.因此我们应该在循环结束后再将'\\0'也拷贝到目的地中,防止程序出现问题.
char* Mycpy(char* dest, char* sour,int sz)
{
assert(dest);
assert(sour);
char* p1 = dest;
for (int i = 0; i < sz; i++)
{
*(dest + i) = *(sour + i);
if (*sour = '\0')
break;
}
return p1;
}
int main()
{
char arr1[40] = { 0 };
char arr2[] = "Manchester United";
int sz = strlen(arr2);
Mycpy(arr1, arr2, sz);
printf("%s\n", arr1);
}
五,strcat函数
原型:
char*strcat(char*destination,const char*source);
功能:将source字符串追加到destination后面,会将dest中‘\0’覆盖。
注意:1, 源字符串必须以 '\0' 结束。
•2,⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
•3,⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• 4,⽬标空间必须可修改。
5,字符串不能自己给自己追加(‘\0’被覆盖,没有终止条件)。
返回值:同strcpy。
实操:
模拟实现:
char* My_cat(char* p1, const char* p2)
{
assert(p1);//断言,p1不为空指针,否则会报错
assert(p2);//断言,p2不为控制着,否则会报错
char* tmp = p1;//保存p1指针的位置,以保证能找到p1所在位置
while (*p1)
{
p1++;//遍历p1字符串到'\0',使得此时p1指针指向终止字符的位置
}
while((*p1++ = *p2++))//将p2字符串的内容逐个字符的复制到p1中
{
;
}
return tmp;
}
六,strcmp函数
返回值:
标准规定:
1 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
2 第⼀个字符串等于第⼆个字符串,则返回0
3 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
4 那么如何判断两个字符串?⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩
实操:
模拟实现:
int my_strcmp (const char * str1, const char * str2)
{
int ret = 0 ;
assert(str1 != NULL);
assert(str2 != NULL);
while(*str1 == *str2)//比较字符串
{
if(*str1 == '\0')//当字符串长度相等时,最后str就为终止符,证明比较完毕
return 0;
str1++;
str2++;//保证两个字符串都是逐个字符比较
}
return *str1-*str2;//最后返回值的实现就是对应ASCII码值的差值
}
七,strncpy函数
1,拷⻉num个字符从源字符串到⽬标空间。
2, 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。
这里不再展示实操和,同理于strcpy。
模拟实现:
八,strncat函数
• Appendsthefirstnumcharactersofsourcetodestination, plus a terminating null-character. (将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 '\0'字符)
• IfthelengthoftheCstringinsourceis less than num,onlythecontentuptotheterminating null-character is copied.(如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾)。
实操:
模拟实现(可以通过count来控制循环次数)
九,strncmp函数
比较的两者的ASCII码值
十,strstr函数
注意:c中和c++中对于strstr的声明不同。
1,返回的是str1字符串中匹配到的位置,因此可通过指针偏移量得到具体位置
int main()
{
char str1[] = "hello world!";
char str2[] = "world!";
char* ret = strstr(str1, str2);
if (ret == NULL)
printf("找不到!\n");
else
printf("%d\n", ret - str1);
return 0;
}
2,如果需要查找字符串的最后一次出现,可以使用strstr函数
3,两个字符串都应该是以'\0' 结尾的字符串
实操:
模拟实现:
情况1:
char* My_str(const char* str1, const char* str2)
{
assert(str1&&str2);//断言 判空
const char*s1=str1;//定义s1和s2指针去做移动
const char*s2=str2;
const char*p=str1;//p指针记录str1的位置
while(*p)//开始循环
{
s1=p;//每次更新起始位置s1
s2=str2;//每次更新s2的起始位置
while(s1!='\0"&&s2!='\0'&&*s1==*s2)//s1和s2不为终止符,且s1==s2时,开始循环
{
s1++;
s2++;
}//1,当s2为0的时候跳出循环 证明寻找完毕,返回当前p(子字符串位置) 2,当两者不相同时跳出循环,此时p++再重新循环判断'\0' ,若还没有碰到主串末尾的话,就要更新s1和s2位置
if(*s2=='\0')
{
return p;
}
p++;
}
return NULL;
}
十一,strtok函数
• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合
• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标 记。
• strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以被strtok函数切分的字符串⼀般都是临时拷⻉的内容并且 可修改。)
• strtok函数的第⼀个参数不为 中的位置。 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串
• strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标 记。
• 如果字符串中不存在更多的标记,则返回 NULL 指针
实操:
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函数
strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说明 的,C语⾔程序启动的时候就会使⽤⼀个全局的变量errno来记录程序的当前错误码,只不过程序启动 的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会将对应 的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都 是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
实操:打印几个错误信息
也可以了解⼀下perror函数,perror函数相当于⼀次将上述代码中的第9⾏完成了,直接将错误信息 打印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
补充:perror函数
上述作为学习笔记,其中由转载和借鉴,如有冲突,请与本人联系。
有错误可以在评论区指出。