🌈write in front :
🔍个人主页 : @啊森要自信的主页
✏️真正相信奇迹的家伙,本身和奇迹一样了不起啊!
欢迎大家关注🔍点赞👍收藏⭐️留言📝>希望看完我的文章对你有小小的帮助,如有错误,可以指出,让我们一起探讨学习交流,一起加油鸭。
文章目录
- ✒️ 前言
- 💯字符分类函数
- 💯 💯字符串转换函数
- 💯 💯 💯strlen的使⽤
- 💯 💯 💯 💯 strlen的3种模拟实现方式
- 📝总结
✒️ 前言
本小节我们将学习字符分类函数,字符串转换函数,使用库函数实现函数(tolower,toupper)
的大小写转换,当然还有字符串转换成整数(isdigit和atoi
),使用(snprintf
)将整数怎么转换回字符串。最后还有strlen函数的三种模拟实现。文章干货满满,让我们学习起来!
💯字符分类函数
这些函数都定义在 ctype.h 头文件中。
它们的参数c
是字符,返回值为非零(true)
或零(false)
。
ctype.h --iscntrl
©- 任何控制字符
-isalpha
© - 检查是否为字母字符(a ~z
或A ~ Z
)
-isupper
© - 检查是否为大写字母字符(A ~Z
)
-islower
© - 检查是否为小写字母字符(A ~Z
)
-isdigit
© - 检查是否为数字字符(十进制 0 ~ 9
)
-isxdigit
© - 检查是否为十六进制数字字符 (包括所有十
进制数字,小写字母a ~ f
,大写字母A ~ F
)
-isalnum
© - 检查是否为字母或数字字符(a ~z
或A ~ Z
或0 ~ 9
)
-isspace
© - 检查是否为空白字符(空白字符:空格‘’、换页‘\f’,换行‘\n’,制表符‘\t’或者垂直制表符‘\v’
等)
-ispunct
© - 检查是否为标点符号字符(任何不属于数字
或者字母
的图形字符(可打印))
-isprint
© - 检查是否为可打印字符(任何可打印字符,包括图形字符和空白字符)
-isgraph
© - 检查是否为除空格外的可打印字符(任何图形字符)
这些函数的使⽤⽅法⾮常类似,如 islower
:
int islower ( int c );
islower
是能够判断参数部分的c
是否是⼩写字⺟的。
通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回0。
#include <ctype.h>
int main()
{
char arr[] = "A SeN yaO Zi XIn";
int i = 0;
while (arr[i])
{
if (islower(arr[i]))
{
arr[i] = arr[i] - 32;
}
putchar(arr[i]);
i++;
}
return 0;
}
例如isalpha
:
#include <ctype.h>
int main()
{
char c = 'a';
if (isalpha(c))//检查是否为==字母==字符( 'a '~'z' 或'A' ~ 'Z')
{
printf("%c is an alphabetic character.\n", c);
}
return 0;
}
💯 💯字符串转换函数
int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写
这两个函数用于转换字母字符的大小写。
例如:
#include <ctype.h>
#include <stdio.h>
int main()
{
char arr[] = "I Am A Student";
int i = 0;
while (arr[i])
{
if (isupper(arr[i]))
{
//arr[i] = arr[i] + 32;
arr[i] = tolower(arr[i]);
}
putchar(arr[i]);
i++;
}
return 0;
}
既然可以字符大小写换,那有没有字符串和数字转换的函数呢?答案是有的。
isdigit
检查单个字符是否是数字atoi
将整个字符串转换为整数
isdigit
函数:
int isdigit(int c);
isdigit
函数用于检查给定字符是否是一个ASCII数字字符。它返回一个非零值或0来指示字符是否是数字(在ctype.h头文件中)。
atoi
函数:
int atoi(const char *str);
atoi
函数用于将字符串转换为相应的整数值。它会跳过字符串前面的空格,然后将字符串中连续的数字字符转换为整数返回。(使用atoi函数需要包含stdlib.h
头文件)
它们都是标准C库中常用的字符串和数字转换函数。
isdigit
:用于检查单个字符c
是否是一个数字字符。如果是数字字符,它会返回c
对应的ASCII
数字值,否则返回0
。
atoi(str)
:用于将字符串str
转换为整数。它会跳过字符串前面的空白字符,然后将字符串中的数字字符转换为相应的整数值返回。
这两个函数经常一起使用,来实现字符串到整数的转换:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
char str[] = "123";
int i = 0;
int sum = 0;
for (i = 0; str[i] != '\0'; i++)
{
if (isdigit(str[i])) //使用isdigit检查每个字符是否是数字
{
sum = sum * 10 + (str[i] - '0');
}//如果是数字,则取它的ASCII值减去'0'得到实际值,累加计算字符串整数值
}
printf("isdigit 逐个转换: %d\n", sum);
int num = atoi(str);//或者直接使用atoi直接转换整个字符串
printf("atoi 直接转换: %d\n", num);
return 0;
}
运行代码如下:
既然有实现字符串到整数的转换,那也可以将整数转换为字符串吧!没错!老铁,杠杠的!
snprintf
函数可以将整数转换为字符串
snprintf
函数原型:
int snprintf ( char * str, size_t n, const char * format, ... );
其中:
char *str
是目标字符串缓冲区指针size_t size
是缓冲区大小缓冲区中要使用的最大字节数。生成的字符串的长度最多为 n-1,为额外的终止 null 字符留出空间。(size_t
是无符号整数类型。)const char *format
是格式字符串...
表示可变参数列表,根据格式字符串,该函数可能需要一系列附加参数,每个参数都包含一个值,用于替换格式字符串中的格式说明符(或指向存储位置的指针,对于n
)。这些参数的数量应至少与格式说明符中指定的值数一样多。该函数将忽略其他参数。
注意:
snprintf
函数的返回类型是一个int
值,表示实际写入目标字符串(不包括终止null字符’\0’)的字符数。
如果返回值等于或大于指定的size,就表示格式化字符串写入目标缓冲区时会发生截断。
如果足够大,则将写入的字符数,不包括终止 null 字符。
如果发生编码错误,则返回负数。
请注意,只有当此返回值为非负且小于 时,字符串才被完全写入。
总结:我们可以把可变参数(...
)设置为整数num,(const char * format
)格式是==“%d”,存储进大小为size_t n
的目标字符数组str==中就可以解决了。
上代码:
#include <stdio.h>
int main()
{
int num = 123456;//定义一个整数num
char str[10] ;//字符数组str作为目标缓冲区
int len = snprintf(str, sizeof(str), "%d", num);
//调用snprintf进行格式化转换,并用len接收返回值
printf("%d\n", len);//查看他返回的写入字符串的个数
if (len < 0)
{
printf("编码错误\n");
return -1;
}
if (len >= sizeof(str))
{
printf("截断,数字长度大于缓冲区大小\n");
}
else
{
printf("字符串转换成功: %s\n", str);
printf("字符串写入成功且第二个元素是: %c\n", str[1]);
}
return 0;
}
代码运行:
在代码中,我没有给字符数组
str
赋值char str[10] ;//字符数组str作为目标缓冲区
,在整数123456调试中我们可以看到str[6]=='\0'
'\0'
哪里来的呢?
我们通过前面知道snprintf
函数的返回值表示实际写入目标字符串的字符数,但不包括结尾的null字符’\0’。
至于null
字符'\0'
是怎么来的,snprintf
在写入字符串时,会自动在结尾添加一个null
字符'\0
’,用来标识字符串的结束。
整数"123456"
转换为字符串,需要6
个字符加1个null
字符,总长度是7
。
因此我们需要在目标字符串内存中预留了null字符所占的空间
int num = 1234567890;//将num重新定义10个整数
char str[10] ;//字符数组str作为目标缓冲区
因此我们需要在目标字符串内存中预留了null字符所占的空间,不然会发生截断
💯 💯 💯strlen的使⽤
size_t strlen ( const char * str );
• 字符串以
'\0'
作为结束标志,strlen
函数返回的是在字符串中'\0'
前⾯出现的字符个数(不包含'\0'
)。
• 参数指向的字符串必须要以'\0'
结束。
• 注意函数的返回值为size_t
,是⽆符号的( 易错 )
•strlen
的使⽤需要包含头⽂件<string.h>
代码实现:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abcdef";//[a b c d e f \0]
char arr2[] = { 'a', 'b', 'c' ,'\0'};//[a b c]
size_t len = strlen(arr2);
printf("%zd\n", len);
return 0;
}
有个易错题:
#include <stdio.h>
#include <string.h>
int main()
{
const char* str1 = "abcdef";//6
const char* str2 = "bbb";//3
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
答案是什么呢?
运行启动:
为什么呢?
strlen
返回的字符串长度类型是size_t
,它是一个无符号整数类型。
str1
长度为6
str2
长度为3
strlen(str2) - strlen(str1)
计算为3 - 6
,结果是-3
- 但是
-3
作为size_t
类型,它是一个无符号整数,所以它的值实际上是大于0的,所以打印的是"str2>str1"
。
注意:
size_t是一个无符号整数类型
例如在32
位系统中:
size_t
最大值为2^32 - 1
-3
作为size_t,
它的值就是2^32 - 1 - 3他的值远远大于0.
💯 💯 💯 💯 strlen的3种模拟实现方式
- 创建临时变量
count
#include <stdio.h>
#include <string.h>
#include <assert.h>
size_t my_strlen1(const char* str)
{
size_t count = 0;
assert(str != NULL);
while (*str)
{
count++;
str++;
}
return count;
}
2.指针减指针
start
指针记录起始位置,str
指针遍历字符串,返回二者差值即为长度。
size_t my_strlen2(const char* str)
{
assert(str);
const char* start = str;
while (*str)
{
str++;
}
return str - start;//两指针相减得到的是中间的元素个数
}
3.函数递归遍历(不使用临时变量,求字符串长度)
size_t my_strlen(const char* str)
{
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str + 1);
}
int main()
{
char arr[] = "abcdef";
size_t len = my_strlen(arr);
printf("%zd\n", len);
return 0;
}
例如,递归abcdef
my_strlen("abcdef");
1+my_strlen("bcdef");
1+1+my_strlen("cdef");
1+1+1+my_strlen("def");
1+1+1+1+my_strlen("ef");
1+1+1+1+1+my_strlen("f");
1+1+1+1+1+1+my_strlen("");
1+1+1+1+1+1+0;
📝总结
通过学习字符分类函数、字符串转换函数和字符串长度计算的原理和用法,我们可以更好地理解字符和字符串的处理方式,并能够灵活运用这些函数进行字符和字符串的处理。这些函数在实际的开发中经常会用到,掌握它们的使用方法对于提高开发效率和代码质量都很重要。
感谢你的收看,如果文章有错误,可以指出,我不胜感激,让我们一起学习交流,如果文章可以给你一个小小帮助,可以给博主点一个小小的赞😘