目录
strlen函数
计算一个字符串的长度。
size_t strlen( const char *string );
所需头文件:<string.h>
参数说明:
const char *string:一个指向字符的指针变量,这个字符串必须以'\0'结尾,否则返回值为随机值。
返回值:
是一个无符号整型,代表字符串的字符数。当函数发生错误时,通常没有返回值。
原理:
当函数接收到指向一个字符串的指针后,开始往后遍历并计数,直到函数找到'\0'。
函数的使用示例:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[10] = "abcdefghi";
printf("%d", strlen(str1));
return 0;
}
输出结果:9
知道了 strlen函数的工作原理之后,我们就可以通过自己书写代码来模拟实现这个库函数了
#include <stdio.h>
#include <assert.h>
#include <string.h>
//模拟实现strlen
size_t my_strlen(const char* str)
{
assert(str);//断言检查传入的指针是否是空指针。
size_t count = 0;
while (*str++ != '\0')
{
count++;
}
return count;
}
int main()
{
char str1[20] = "abbbcde";
printf("%d\n", my_strlen(str1));
return 0;
}
输出结果:7
strcpy函数
复制一个字符串到另外一个字符数组里。
char *strcpy( char *strDestination, const char *strSource );
所需头文件:<string.h>
参数说明:
char *strDestination: 指向用来接收的字符数组。
const char *strSource:指向被复制的字符串。
返回值:返回一个指针,指向接收的字符数组。
原理: 令*dest等于*src,两个同时加一,直到将src里的'\0'复制到dest里。
注意: 源字符串必须以'\0'结尾,同时目标空间必须有足够大的空间来容纳源字符串
函数的使用示例 :
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("%s\n",strcpy(str2, str1));
return 0;
}
输出结果:abbbcde。
知道了 strcpy函数的工作原理之后,我们就可以通过自己书写代码来模拟实现这个库函数了
#include <stdio.h>
#include <assert.h>
#include <string.h>
//模拟实现strcpy
char* my_strcpy(char* dest, const char* src)
{
assert(dest);
assert(src);
char* ret = dest;
while (*dest++ = *src++)//\0复制完成之后整个表达式的结果为0,退出循环
{
}
return ret;
}
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("%s\n",my_strcpy(str2, str1));
return 0;
}
输出结果:abbbcde。
strcat函数
将源字符串追加到目标字符串后。
char *strcat( char *strDestination, const char *strSource );
所需头文件:<string.h>
参数说明:
char *strDestination:指向被追加字符串的指针变量
const char *strSource:指向追加内容的指针变量
返回值: 返回一个指针,指向目标字符数组。
原理:先找到被追加字符串的'\0',从此处开始,将追加内容一个一个往后复制,直至到追加内容的'\0'.
注意: 源字符串必须以'\0'结尾,同时目标空间必须有足够大的空间来容纳源字符串。若追加内容为被追加字符串本身,则会陷入死循环。
函数的使用示例 :
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("%s", strcat(str1, str2));
return 0;
}
输出结果:abbbcdebbc
知道了 strcat函数的工作原理之后,我们就可以通过自己书写代码来模拟实现这个库函数了
#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest);
assert(src);
char* ret = dest;
while (*dest != '\0')//先找到'\0'
{
dest++;
}
while (*dest++ = *src++)//开始覆盖
{
}
return ret;
}
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("%s", my_strcat(str1, str2));
return 0;
}
输出结果:abbbcdebbc
strcmp函数
判断两个字符串是否相等。
int strcmp( const char *string1, const char *string2 );
所需头文件:<string.h>
参数说明: const char *string1:指向需要比较的字符串1的指针
const char *string2:指向需要比较的字符串2的指针
返回值:当返回值为0时,代表两个字符串相等;返回值非0时,代表两个字符串不等,其中大于0的数代表字符串1的ASCII值更大 ,反之则字符串2的ASCII码更大。
原理:通过两个指针指向的字符进行比较,相等则下一个,直至两个都为'\0',此时退出并返回0;遇到不相等时,返回字符ASCII值的差值。
函数使用示例:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("%d", strcmp(str1, str2));
return 0;
}
输出结果:-1
知道了 strcmp函数的工作原理之后,我们就可以通过自己书写代码来模拟实现这个库函数了
#include <stdio.h>
#include <assert.h>
//模拟实现strcmp
int my_strcmp(char* str1, const char* str2)
{
assert(str1);
assert(str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("%d", my_strcmp(str1, str2));
return 0;
}
输出结果:-1
strstr函数
判断字符串str2是否是str1的子串 ,同时返回其地址。
char *strstr( const char *string, const char *strCharSet );
所需头文件:<string.h>
参数说明: const char *string:指向字符串str1的指针
const char *strCharSet :指向要查找的字符串的指针
返回值:若str1里面包含str2,则返回str2第一次出现的地址;若不存在,则返回空指针NULL。
原理:对比 string和strCharSet 所指向的字符,字符相等时开始遍历,若遍历过程中相等直至strCharSet 指向'\0',则返回开始遍历时的地址;若遍历过程出现不相等的情况,则退出遍历,下一次遍历从string的下一个字符开始。
函数使用示例:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
/*
打印这个字符串在目标字符串哪个位置开始的
*/
printf("从第%d个位置开始第一次出现", 1 + strstr(str1, str2) - str1);
return 0;
}
输出结果:从第3个位置开始第一次出现
知道了 strstr函数的工作原理之后,我们就可以通过自己书写代码来模拟实现这个库函数了
#include <stdio.h>
#include <assert.h>
char* my_strstr(char* dest, const char* src)
{
assert(dest);
assert(src);
char* s1 = NULL;//遍历dest的指针
char* s2 = NULL;//遍历src的指针
char* start = dest;//指向每次开始的位置,首字符不相同时start+1,从后面再开始比较
/*
*/
while (*start != '\0')//*start != '\0'指的是str1还没被遍历完,后面还可能存在匹配的字符串
{
s2 = src;
s1 = start;
/*
首字符相同时才有继续比较的必要,当之后的字符不匹配时跳出第一个while循环,检查*s2是否为\0,如果是,则代表
整个src遍历完了,而且和start开始往后的字符串一样,此时返回start指针就可以找到匹配的位置了;如果此时*s2不是\0
则代表还没遍历完就因为和start后面的不一样而退出循环了,此时直接start++,找dest的下一个字符重新开始作比较。
如果整个大循环都结束了,还没有返回start,说明dest里面没有src指向的字符串,返回一个空指针NULL;
*/
while (*s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return start;
}
start++;
}
return NULL;
}
int main()
{
char str1[20] = "abbbcde";
char str2[20] = "bbc";
printf("从第%d个位置开始第一次出现", 1 + my_strstr(str1, str2) - str1);
return 0;
}
输出结果:从第3个位置开始第一次出现
注意:
这些函数在使用过程中尤其要注意字符串'\0'的问题以及空间大小,为防止越界访问,我们可以使用strncpy、strncat、strncmp,这些函数会比strcpy、strcat、strcmp多一个控制操作字符数量参数,相对安全些,但也只是相对,因此无论使用何种字符串库函数,都要多加注意。