
🔥个人主页:艾莉丝努力练剑
🍓专栏传送门:《C语言》
🍉学习方向:C/C++方向
⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平
前言:前面几篇文章介绍了c语言的一些知识,包括循环、数组、函数、VS实用调试技巧、函数递归、操作符、指针等,在这篇文章中,我将介绍字符函数和字符串函数的一些重要知识点!对字符函数和字符串函数感兴趣的友友们可以在评论区一起交流学习!

C语言中有一系列的函数是专门做字符分类的,也就是一个字符是属于什么类型的字符的。这些函数的使用都需要包含⼀个头文件是 ctype.h
字符分离函数有这些:

这些函数的使用方法非常类似,我们就讲解一个函数的事情,其他的非常类似:
int islower ( int c );islower 是能够判断参数部分的 c 是否是小写字目的。通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。
我们做个练习练练手:
要求:写一个代码,将字符串中的小写字母转大写,其他字符不变。
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c))
c -= 32;
putchar(c);
i++;
}
return 0;
}C语言提供给我们2个字符转换函数:
int tolower(int c);//将参数传进去的大写字符转小写
int toupper(int c);//将参数传进去的小写字母转大写将小写转大写是-32完成的效果,有了转换函数,就可以直接使用tolower函数。
代码实现:
#include<stdio.h>
#include<ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower)
c = toupper;
putchar(c);
i++;
}
return 0;
}代码块原型:
size_t strlen(const char* str);功能:统计参数str指向的字符串的长度,统计的是字符串中'\0'之前的字符的个数; 参数: str:指针,指向了要统计长度的字符串; 返回值:返回了str指向的字符串的长度,返回的长度不会是负数,所以返回类型是size_t。
注意:size_t 表示无符号整型,即>=0;
包括unsigned int,unsigned long,unsigned long long
要求: 1、字符串以'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面抽闲的字符个数(不包含'\0'); 2、参数指向的字符串必须要以'\0'结束; 3、注意函数的返回值为size_t,是无符号的(容易错); 4、strlen的使用需要包含头文件。
#include<stdio.h>
#include<string.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str2) > 0)
{
printf("str2>str1\n");
}
else
{
printf("str1>str2\n");
}
return 0;
}也可以这样:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{
int count = 0;
assert(str);
while (*str)
{
count++;
str++;
}
return count;
}
int main()
{
int len = my_strlen("abcdef");
printf("%d\n", len);
return 0;
}strlen的模拟实现:
方法1:计数器方式
int my_strlen(const char* str)
{
int count = 0;
assert(str);
while (*str)
{
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);
}如果不能在函数内部创建临时变量,就使用递归的方法求字符串长度 :
int main()
{
char arr[] = "abc";
size_t len = my strlen(arr);
printf("%zu\n", len);
return 0;
}

先递推,再回归。
方法3:指针-指针的方式
int my_strlen(char *s)
{
assert(str);
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}原型:
char* strcpy(char* destination, const char* source);功能:字符串拷贝,拷贝到源头字符串的\0为止; 参数: destination:指针,指向目的地空间; source:指针,指向源头数据; 返回值: strcat函数返回的是目标空间的起始地址 。
要求:
1、源字符串必须以'\0'结束; 2、会将源字符串中的'\0'拷贝到目标空间; 3、目标空间必须足够大,以确保能存放源字符串; 4、目标空间必须可修改。
strcpy的模拟实现:
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))
{
;
}
return ret;
}注意: 1.参数顺序 2.函数的功能,停止条件 3.assert 4.const修饰指针 5.函数返回值 6.题目出自《高质量C/C++编程》书籍最后的试题部分
我们在数组里面存放一个“hello world” :

数组名是地址,地址是一个编号,且是常量,不能被修改; 地址是指向空间的,但是地址本身不是空间。


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

注:" " 指向了空字符串; 空指针没有任何指向。
这个模拟实现的效果还不够好,我们还可以再改一下——

参数、返回类型和功能要一致。
char* strcat(char* destination, const char* source);功能: 字符串追加,把source指向的源字符串中的所有字符都追加到destination指向的空间中。 参数: destination:指针,指向目的地空间; source:指针,指向源头数据; 返回值: strcat函数返回的是目标空间的起始地址 。
要求:
1、源字符串必须以'\0'为结束标志; 2、目标字符串中也得有\0,否则没办法知道追加从哪里开始; 3、目标空间必须足够大,能容纳源字符串的内容; 4、目标空间必须可修改。
思考:字符串自己给自己追加会怎么样?
模拟实现:
char* my_strcat(char* dest, const char* src);
{
char* net = dest;
assert(dest != NULL);
assert(src != NULL);
while (*dest)
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return ret;
}我们还是以"hello world"为例子,便于友友们理解追加:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}输出结果:

注意:追加是在末尾追加的 。
大家观察strcat的代码块就会发现,它返回的是char*,并且strcat函数返回的是目标空间的起始地址 ,我们这边可以用char*的指针来接受返回值:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
char* r = strcat(arr1, arr2);
printf("%s\n", arr1);
printf("%s\n", r);
return 0;
}也可以完成功能:

代码块:
int strcmp(const char* str1, const char* str2);功能:用来比较str1和str2指向的字符串,从两个字符串的第一个字符开始比较,如果两个字符的ASCLL码值相等,则比较下一个字符,直到遇到不相等的两个字符或者字符串结束。
参数: str1:指针,指向要比较的的第一个字符串 str2:指针,指向要比较的的第二个字符串
返回值: 标准规定—— 1.第一个字符串大于第二个字符串,则返回大于0的数字; 2.第一个字符串等于第二个字符串,则返回0; 3.第一个字符串小于第二个字符串,则返回小于0的数字。
strcmp—string compare—字符串比较



代码实现(1):
字符串"abcdef"和"abq"比大小:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abq";
int r = strcmp(arr1, arr2);
if (r > 0)
printf("arr1>arr2\n");
else if (r < 0)
printf("arr1<arr2\n");
else
printf("arr1=arr2\n");
return 0;
}输出结果:

代码实现(2):
字符串"abcdef"和"abcdef"进行比较:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdef";
int r = strcmp(arr1, arr2);
if (r > 0)
printf("arr1>arr2\n");
else if (r < 0)
printf("arr1<arr2\n");
else
printf("arr1=arr2\n");
return 0;
}输出结果:

代码实现(3):
字符串"abc"和"abcdef"进行比较:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abc";
char arr2[] = "abcdef";
int r = strcmp(arr1, arr2);
if (r > 0)
printf("arr1>arr2\n");
else if (r < 0)
printf("arr1<arr2\n");
else
printf("arr1=arr2\n");
return 0;
}结果输出:

代码实现(4):
字符串"abcdef"和"abcd"比大小:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcd";
int r = strcmp(arr1, arr2);
if (r > 0)
printf("arr1>arr2\n");
else if (r < 0)
printf("arr1<arr2\n");
else
printf("arr1=arr2\n");
return 0;
}输出结果:

#include<stdio.h>
#include<string.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;//解决了大于的情况
else
return -1;//解决了小于的情况
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcd";
int r = strcmp(arr1, arr2);
if (r > 0)
printf("arr1 > arr2\n");
else if (r < 0)
printf("arr1 < arr2\n");
else
printf("arr1 == arr2\n");
return 0;
}

总结: strcpy strcat strcmp 这些是长度不受限的字符串函数
往期回顾:
C语言指针深入详解(六):sizeof和strlen的对比,【题解】数组和指针笔试题解析、指针运算笔试题解析
结语:本篇文章就到此结束了,本文为友友们分享了一些字符函数和字符串函数相关的重要知识点,如果友友们有补充的话欢迎在评论区留言,下一期我们将继续介绍这个字符函数和字符串函数剩下的一些重要知识点,感谢友友们的关注与支持!