参考上课内容及网上文章总结,仅供自己复习使用,非原创。
代码于vs2022测试。
字符串就是一串零个或多个字符,并且以一个模式全为0的NUL字节结尾。
1.strlen()
字符串长度就是它所包含的的字符数量。
//求字符串长度
int my_strlen(const char* str)
{
assert(str != NULL); //检查指针的有效性
int i = 0;
while (*str++)
{
i++;
}
return i;
}
int main()
{
const char* str = "abcdef";
printf("%d\n", strlen(str));
printf("%d\n", my_strlen(str));
}
这里要注意:
在string文件中strlen()函数的返回值是无类型的,是unsigned int类型,其值永远大于零
因此,不能写str1 - str2 > 0。
2.strstr()
字符串查找函数。
查找字符串函数,前面是被查找的字符串,后面是要查找的字符串
如果找到返回所找字符串首字符地址,如果找不到返回NULL
char* my_strstr(const char* str1,const char* str2)
{
assert(str1 && str2);
char* p1 = NULL;
char* p2 = NULL;
char* cur = (char*)str1;
if (*str2 == '\0')
{
return (char*)str1;
}
while (cur++)
{
p1 = cur;
p2 = (char*)str2;
while ((*p1 != '\0') && (*p2 != '\0') && *p1 == *p2)
{
}
if (*p2 == '\0')
{
return cur;//找到字串
}
if (*p1 == '\0')
{
return NULL;
}
}
return NULL;//找不到字串
}
int main()
{
char str1[20] = "abcdefghijk";
char str2[20] = "def";
char* ret = strstr(str1, str2);
if (ret == NULL)
{
printf("字串不存在\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
3.长度不受限的字符串函数
3.1strcpy()
复制字符串函数,将一个字符串的内容拷贝到另一个字符串中,覆盖之前内容!(包括'\0')。
char* my_strcpy(char* str1, const char* str2)
{
assert(str1 != NULL);
assert(str2 != NULL);
char* ret = str1;
while(*str1++ = *str2++) {}
return ret; //返回目的空间起始地址
}
int main()
{
char p1[10];
char p2[10] = "a,b,c";
printf("%s\n", strcpy(p1, p2));
printf("%s\n", my_strcpy(p1, p2));
return 0;
}
3.2strcmp()
字符串比较函数。
比较的是字符串对应的ASCII码值的大小,而不是字符串的长度。
如果都相等返回0;
如果前面>后面,返回一个大于0的数字;
如果前面<后面,返回一个小于0的数字。
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1++ == *str2++)
{
if (*str1 == '\0')
{
return 0;
}
}
if (*str1 > *str2)
{
//大于
return 1;
}
if (*str1 < *str2)
{
//小于
return -1;
}
}
int main()
{
const char* str1 = "a,b,c";
const char* str2 = "d,e,f";
printf("%d\n", strcmp(str1, str2)); // 输出-1
const char* str3 = "a,b,c";
const char* str4 = "a,b,c";
printf("%d\n", strcmp(str3, str4)); //输出0
}
3.3strcat()
字符串连接函数,把一个字符串追加到另一个后面。
char* my_strcat(char* str1, const char* str2)
{
assert(str1 != NULL);
assert(str2 != NULL);
char* ret = str1;
//找到第一个字符串尾
/*while (*str1++) {};*/
while (*str1 != '\0')
{
str1++;
}
//补
while (*str1++ = *str2++) {};
return ret;
}
int main()
{
char str1[20] = "a,b,c";
char str2[] = "->d,e,f";
printf("%s\n", strcat(str1, str2));
printf("%s\n", my_strcat(str1, str2));
return 0;
}
注意:
(1)源字符串必须以'\0'结束
(2)目标空间必须有足够大的空间能容纳下源字符串的内容
(3)目标空间必须可修改
(4)不能自己给自己追加,那样程序会崩溃
4.长度受限的字符串函数
为什么要限制长度?
是为了防止一个难以预料的长字符串从它们的目标数组中溢出。
4.1strncpy()
拷贝n个字符到另一个字符串中.
如果源字符串长度小于n,那么则将/0拷贝进去.
char* my_strncpy(char* str1, const char* str2, int num)
{
assert(str1 && str2);
char* ret = str1;
for (int i = 0; i < num; i++)
{
if (*str2 != '\0')
{
*str1++ = *str2++;
}
else
{
*str1++ = '\0';
}
}
return ret;
}
int main()
{
char str1[] = "a,b,c";
char str2[] = "d,";
printf("%s\n", strncpy(str1, str2, 4));
printf("%s\n", my_strncpy(str1, str2,4));
}
4.2strncmp()
int my_strncmp(const char* str1, const char* str2, int n)
{
assert(str1 && str2);
for (int i = 0; i < n; i++)
{
if (*str1 < *str2)
{
return -1;
}
else if (*str1 > *str2)
{
return 1;
}
else
{
str1++;
str2++;
}
}
return 0;
}
4.3strncat()
char* my_strncat(char* str1, const char* str2, int n)
{
assert(str1 && str2);
char* ret = str1;
while(*str1++){}
for (int i = 0; i < n; i++)
{
if (*str1 != '\0')
{
*str1++ = *str2++;
}
else
{
/**str1 = '\0';*/ //如果传入参数的是字符串数组,其已经初始化过,
//因此不需要
return ret;
}
}
/**str1 = '\0';*/
return ret;
}
int main()
{
char str1[50] = "a,b,c";
char str2[] = "d,e,f,g,h";
printf("%s\n", strncat(str1, str2,4));
printf("%s\n", my_strncat(str1, str2, 4));
}