C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。本篇文章为大家详解八个常用的字符串操作函数,同时我们尝试模拟实现该函数,加深我们对函数的认识和了解。
目录
1. strlen
1.1 strlen()函数简介
1.2 strlen()的基本使用
1.3 模拟实现strlen()函数
2. strcpy
2.1 strcpy()函数简介
2.2 strcpy()的基本使用
2.3 模拟实现strcpy()函数
3. strcat
3.1 strcat()函数简介
3.2 strcat()的基本使用
3.3 模拟实现strcat()函数
4. strcmp
4.1 strcmp()函数简介
4.2 strcmp()的基本使用
4.3 模拟实现strcmp()函数
5. strncpy
5.1 strncpy()函数简介
5.2 strncpy的基本使用
5.3 模拟实现strncpy()函数
6. strncat
6.1 strncat() 函数简介
6.2 strncat的基本使用
6.3 模拟实现strncat()函数
7. strncmp
7.1 strncmp()函数简介
7.2 strncmp的基本使用
7.3 模拟实现strncmp()函数
8. strstr
8.1 strstr()函数简介
8.2 strstr的基本使用
8.3 模拟实现strstr()函数
1. strlen
1.1 strlen()函数简介
strlen(): 返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
函数原型
注:
需包含<string.h>头文件
字符串以 '\0' 作为结束标志。
参数指向的字符串必须要以 '\0' 结束。
注意函数的返回值为size_t,是无符号的(unsigned int)( 易错 )
1.2 strlen()的基本使用
int main() { const char* p = "Hello world"; int len = (int)strlen(p); printf("%d\n", len); return 0; }
1.3 模拟实现strlen()函数
创建临时变量
#include <stdio.h> #include <assert.h> // 创建临时变量实现strlen int my_strlen(const char* str) { int count = 0; assert(str);//不为空指针 while (*str) { count++; str++; } return count; } int main() { const char* ch = "abcdef"; int len = my_strlen(ch); printf("%d\n", len);// 6 return 0; }
不创建临时变量(递归实现)
// 不创建临时变量实现strlen int my_strlen(const char* str) { if (*str == '\0') { return 0; } else { return 1 + my_strlen(str + 1); } } int main() { const char* ch = "abcdef"; int len = my_strlen(ch); printf("%d\n", len);// 6 return 0; }
2. strcpy
2.1 strcpy()函数简介
strcpy(): 将源指向的C字符串复制到目标指向的数组中,包括终止空字符(并在该点停止)。
函数原型
注:Destination(目的地),Source(源自)
需包含<string.h>头文件
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
2.2 strcpy()的基本使用
int main() { char ch1[20] = { 0 }; const char ch2[] = "hello world"; strcpy(ch1, ch2); printf("%s\n", ch1); return 0; }
2.3 模拟实现strcpy()函数
#include <stdio.h>
#include <assert.h>
//模拟实现strcpy函数
char* my_strcpy(char* des, const char* sou)
{
char* ret = des;
assert(des && sou);//不为空指针
// 拷贝
while (*des++ = *sou++)
{
;
}
return ret;//返回目标地址
}
int main()
{
char ch1[20] = { 0 };
const char ch2[] = "hello world";
my_strcpy(ch1, ch2);
printf("%s\n", ch1); // hello world
return 0;
}
3. strcat
3.1 strcat()函数简介
strcat(): 将源字符串的副本追加到目标字符串。目标中的终止空字符(\0)被源的第一个字符覆盖,并在目标中两者的连接形成的新字符串的末尾包含一个空字符(\0)。
函数原型
注:
需包含<string.h>头文件
源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改
不可自己追加追加
3.2 strcat()的基本使用
int main() { char ch1[30] = "hello "; const char ch2[] = "world"; strcat(ch1, ch2); printf("%s\n", ch1); return 0; }
3.3 模拟实现strcat()函数
#include <stdio.h>
#include <assert.h>
//模拟实现strcat
char* my_strcat(char* des, const char* sou)
{
assert(des && sou);
char* ret = des;
//找到目标字符串的‘\0’
while (*des)
{
des++;
}
//追加
while (*des++ = *sou++)
{
;
}
return ret;//返回目标地址
}
int main()
{
char ch1[30] = "hello ";
const char ch2[] = "world";
my_strcat(ch1, ch2);
printf("%s\n", ch1);// hello world
return 0;
}
4. strcmp
4.1 strcmp()函数简介
strcmp(): 比较每个字符串的第一个字符。如果它们相等,则继续执行以下对,直到字符不同或到达一个终止的空字符为止。
函数原型
返回值:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
注:比较大小的依据:不是比较两个字符串的长度,而是比较两个字符串中字符的ASCII码值大小
4.2 strcmp()的基本使用
int main() { const char* p1 = "abcdef";// a 的ASCII码为 97 const char* p2 = "bcdef";// b 的ASCII码为 98 int ret = strcmp(p1, p2); printf("%d\n", ret); return 0; }
4.3 模拟实现strcmp()函数
#include <stdio.h>
#include <assert.h>
// 模拟实现strcmp
int my_strcmp(const char* des, const char* sou)
{
assert(des && sou);
//如果两个字符相等,继续往后面找到不同字符进行比较
while (*des == *sou)
{
//元素全部相等
if (*des == '\0')
{
return 0;
}
des++;
sou++;
}
//返回值
return *des - *sou;
}
int main()
{
const char* p1 = "abcdef";// a 的ASCII码为 97
const char* p2 = "bcdef";// b 的ASCII码为 98
int ret = my_strcmp(p1, p2);
printf("%d\n", ret);
return 0;
}
5. strncpy
5.1 strncpy()函数简介
strncpy():将源字符串的num个字符复制到目标。如果源字符串的结束在复制字符之前找到,目标将用0填充,直到总共向其写入了num字符 。
函数原型
注:
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
5.2 strncpy的基本使用
int main() { char p1[20] = "abcd"; const char p2[] = "hello"; strncpy(p1, p2,2 ); printf("%s\n", p1); return 0; }
5.3 模拟实现strncpy()函数
#include <stdio.h>
#include <assert.h>
// 模拟实现strncpy
char* my_strncpy(char* des, const char* sou, unsigned int num)
{
assert(des && sou);
char* ret = des;
//拷贝
while (num && (*des++ = *sou++))//num范围
{
num--;
}
//范围大于源字符串全部置0
if (num)
{
while (--num)//先--再使用,避免多进入循环一次
{
*des++ = '\0';
}
}
return des;//返回目标值
}
int main()
{
char p1[20] = "abcd\0aaaaaaa";
const char p2[] = "hello";
my_strncpy(p1, p2, 8);
printf("%s\n", p1);
return 0;
}
6. strncat
6.1 strncat() 函数简介
strncat(): 将源字符串的num个字符加上一个结束空字符追加到目标。如果源字符串中的追加字符串的长度小于num,则只复制终止空字符之前的内容。
函数原型
注:
需包含<string.h>头文件
如果源字符串中的追加字符串的长度小于num,则只复制终止空字符之前的内容。
6.2 strncat的基本使用
int main() { char p1[20] = "hello"; const char p2[] = "world"; strncat(p1, p2, 3); printf("%s\n", p1); return 0; }
6.3 模拟实现strncat()函数
#include <stdio.h>
#include <assert.h>
// 模拟实现strncat
char* my_strncat(char* des, const char* sou, unsigned int num)
{
assert(des && sou);//不为空
char* ret = des;
//找到目标字符串的'\0'
while (*des)
{
des++;
}
//按给定范围追加
while (num && (*des = *sou))
{
num--;
des++;
sou++;
}
return ret;//返回目标地址
}
int main()
{
char ch1[20] = "hello\0aaaaaaa";
char ch2[] = "world";
my_strncat(ch1, ch2, 8);
printf("%s\n", ch1);
return 0;
}
7. strncmp
7.1 strncmp()函数简介
strncmp(): 比较到出现一个字符串结束或者num个字符全部比较完
函数原型
返回值
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字注:
比较是两个字符串一起比较相同num范围
比较的是两个字符串中字符的ASCII码值大小
7.2 strncmp的基本使用
int main() { const char* p1 = "abcdef"; const char* p2 = "bcde"; int ret = strncmp(p1, p2, 2);//比较的是ab-bc printf("%d\n", ret); return 0; }
7.3 模拟实现strncmp()函数
#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* p1, const char* p2, unsigned int num)
{
assert(p1 && p2);//不为空
//先找到不相同的字符
while (num && (*p1 == *p2))
{
num--;
p1++;
p2++;
}
if (num == 0)//num个字符都相等
return 0;
else
return *p1 - *p2;
}
int main()
{
const char* p1 = "dbcdef";
const char* p2 = "dzde";
int ret = my_strncmp(p1, p2, 2);//比较的是db-dz
printf("%d\n", ret);// -24
return 0;
}
8. strstr
8.1 strstr()函数简介
strstr(): 查找子字符串,返回指向目标字符串中需要查找到的第一个出现的指针,如果str2不是str1的一部分,则返回一个空指针
函数原型
注:
如果源字符串中出现多个需查找的子字符串,返回的是第一个出现的地址
8.2 strstr的基本使用
int main() { const char* p1 = "abcdefg"; const char* p2 = "cd"; char* ret = strstr(p1, p2); printf("%s\n", ret); return 0; }
8.3 模拟实现strstr()函数
#include <stdio.h>
#include <assert.h>
//模拟实现strstr
char* my_strstr(const char* p1, const char* p2)
{
assert(p1 && p2);//不为空
char* s1 = NULL;
char* s2 = NULL;//使p1和p2发生改变
char* cur = (char*)p1;//用来存放查找到地址
if (*p2 == '\0')//查找子字符串只存放了'\0'
{
return (char*)p1;
}
//开始查找
while (*cur)
{
s1 = cur;
s2 = (char*)p2;
//查找到一个相同的字符串,判断后面是不是全部相同,两个字符串不为\0,s1等于s2
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
// 判断s1被查完既查找字符串长度大于源字符串abc-abcd
if (*s1 == '\0')
{
return NULL;
}
//判断p2是否全部查找完了
if (*s2 == '\0')
{
return cur;//返回第一次出现的地址
}
cur++;
}
return NULL;//源字符串查找完了没找到子字符串中的内容,返回空指针
}
int main()
{
const char* p1 = "abcdefg";
const char* p2 = "cd";
char* ret = my_strstr(p1, p2);
printf("%s\n", ret);// cdefg
return 0;
}