strcspn和strspn的区别
1.函数原型
size_t strcspn(const char *str1, const char *str2);
size_t strspn(const char *str1, const char *str2);
2.函数功能
- strcspn: 检索字符串 str1 中第一个在字符串 str2 中出现的字符下标。返回 str1 中第一个在字符串 str2 中出现的字符的下标。
- strspn: 检索字符串 str1 中第一个不在字符串 str2 中出现的字符下标。返回 str1 中第一个不在字符串 str2 中出现的字符下标。
3.strcspn和strspn的区别
举例说明两者不同:
- 假设str1[20] = “HelloWorld”; str2[20] = “eo”;
使用strcspn(str1,str2),就是在str1中找到第一次出现“e”或者“o”的位置,返回应该是1;
使用strspn(str1,str2),就是在str1中找到第一个不是“e”并且也不是“o”的位置,返回应该是0。
int main()
{
char str1[20] = "HelloWorld";
char str2[20] = "eo";
printf("\r\nstrcspn test\r\n");
printf("str1:%s\r\n",str1);
printf("str2:%s\r\n",str2);
printf("第一个匹配的字符是在 %d\n", strcspn(str1,str2));
printf("\r\nstrspn test\r\n");
printf("str1:%s\r\n",str1);
printf("str2:%s\r\n",str2);
printf("第一个不匹配的字符是在 %d\n", strspn(str1,str2));
system("pause");
return 0;
}
运行结果如下:
结果与预想一致。
注意: str1所查找的字符包含str2中的所有字符。
- 当str1中没有str2中的字符时,显然,strspn(str1,str2)应该返回0,而strcspn(str1,str2)返回字符串str1的最大长度。
假设str1[20] = “HelloWorld”; str2[20] = “a”;
使用strcspn(str1,str2),就是在str1中找到第一次出现“a”的位置,返回应该是10(即strlen(str1));
使用strspn(str1,str2),就是在str1中找到第一个不是“a”的位置,返回应该是0。
int main()
{
char str1[20] = "HelloWorld";
char str2[20] = "a";
printf("\r\nstrcspn test\r\n");
printf("str1:%s\r\n",str1);
printf("str2:%s\r\n",str2);
printf("第一个匹配的字符是在 %d\n", strcspn(str1,str2));
printf("\r\nstrspn test\r\n");
printf("str1:%s\r\n",str1);
printf("str2:%s\r\n",str2);
printf("第一个不匹配的字符是在 %d\n", strspn(str1,str2));
system("pause");
return 0;
}
运行结果如下:
- 当str1中所有字符都在str2中,显然,strcspn(str1,str2)应该返回0,而strspn(str1,str2)返回字符串str1的最大长度。
假设str1[20] = “HelloWorld”; str2[20] = “HelloWorld”;
使用strspn(str1,str2),返回应该是10(即strlen(str1));
使用strcspn(str1,str2),返回应该是0。
4.源码
/************************************************************************
*功能:检索字符串 str1 开头连续有几个字符都不含字符串 str2 中的字符
*输入:str1:要被检索的 C 字符串。
* str2:该字符串包含了要在 str1 中进行匹配的字符列表。
*输出:无
*返回:返回 str1 开头连续都不含字符串 str2 中字符的字符数。
************************************************************************/
size_t Mystrcspn(const char *str1, const char *str2)
{
// map有32个字节的大小,也就是256个bit,可把map看做一个2维数组[32][8]
unsigned char map[32] = {0};
int count = 0;
// 每个ASCII码(设为c)有7bit,共128个。
// map数组作为位图记录每个ASCII码是否出现过。map一个字节可以记录8个ASCII码
// 如“0”的ASCII码是48,那么map[48/8]就是“0”在位图中的第几个字节
// 而48 & 7(换成二进制就是0011 0000 & 0000 0111,一个字节8bit,所以&7)可以定位到这个字节的第几个bit
while(*str2)
{
map[*str2 >> 3] |= (1 << (*str2 & 7));
str2++;
}
map[0] |= 1;//0在ascii中表示空,所以前面*str退出时一定是空,所以置位
while(!(map[*str1 >> 3] & (1 << (*str1 & 7))))
{
count++;
str1++;
}
return count;
}
/************************************************************************
*功能:检索字符串 str1 中第一个不在字符串 str2 中出现的字符下标
*输入:str1:要被检索的 C 字符串。
* str2:该字符串包含了要在 str1 中进行匹配的字符列表。
*输出:无
*返回:返回 str1 中第一个不在字符串 str2 中出现的字符下标。
************************************************************************/
size_t Mystrspn(const char *str1, const char *str2)
{
// map有32个字节的大小,也就是256个bit,可把map看做一个2维数组[32][8]
unsigned char map[32] = {0};
int count = 0;
// 每个ASCII码(设为c)有7bit,共128个。
// map数组作为位图记录每个ASCII码是否出现过。map一个字节可以记录8个ASCII码
// 如“0”的ASCII码是48,那么map[48/8]就是“0”在位图中的第几个字节
// 而48 & 7(换成二进制就是0011 0000 & 0000 0111,一个字节8bit,所以&7)可以定位到这个字节的第几个bit
while(*str2)
{
map[*str2 >> 3] |= (1 << (*str2 & 7));
str2++;
}
//map[0] |= 1;//0在ascii中表示空,所以前面*str退出时一定是空,所以置位
while((map[*str1 >> 3] & (1 << (*str1 & 7))))
{
count++;
str1++;
}
return count;
}