本章重点
重点介绍处理字符和字符串的库函数的使用和注意事项
求字符串长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍
strncpy
strncat
strncmp
字符串查找
strstr
strtok
前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在
常量字符串 中或者 字符数组 中。
字符串常量 适用于那些对它不做修改的字符串函数
- 函数介绍
1.1 strlen(求字符串长度的库函数)
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
含 ‘\0’ )。
size_t strlen ( const char * str );
参数指向的字符串必须要以 ‘\0’ 结束。
注意函数的返回值为size_t,是无符号的( 易错 )
学会strlen函数的模拟实现
int main()
{
char ch[] = "hello world";
size_t ret=strlen(ch);
printf("%d\n", ret);
return 0;
}
strlen的模拟实现
size_t strlen ( const char * str );我们按照他的格式模拟实现
//第一种普通的方法实现
int my_strlen(const char*p)
{
int count = 0;
while (*p != '\0')
{
p++;
count++;
}
return count;
}
int main()
{
char ch[] = "hello world";
int ret=my_strlen(ch);
printf("%d\n", ret);
return 0;
}
//第二种是指针减指针的方法
int my_strlen(char* p)
{
char* start = p;
while (*start != '\0')
{
start++;
}
return start - p;
}
int main()
{
char ch[] = "hello world";
int ret=my_strlen(ch);
printf("%d\n", ret);
return 0;
}
第一种就是普通的方法,从首字符开始每移动一个字符,count+1,当遇到\0的时候就会跳出循环。
第二种就是利用指针-指针的方法(指针减指针绝对差值等于俩个元素之间的元素的个数)
2 strcpy(拷贝字符串函数的)
strcpy函数是一个用于拷贝字符串的函数,即将一个字符串中的内容拷贝到另一个字符串中(会覆盖原字符串内容)。它的参数是两个指针,第一个指向的是拷贝字符串的目的地的起始位置,即要将字符串拷贝到什么地方;第二个指向的是要拷贝字符串的内容的起始位置,即需要拷贝的字符串。它的返回值是目标空间的起始位置。
注意点:
源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。
strlen的用法
int main()
{
char ch1[20] = { 0 };
char ch2[] = "hello world";
strcpy(ch1, ch2);
printf("%s\n", ch1);
return 0;
}
```c
strcpy的模拟实现
char* my_strcpy(char* p1, char* p2)
{
char* ret = p1;
while (*p1++ = *p2++)
{
;
}
return ret;
}
int main()
{
char ch1[20] = { 0 };
char ch2[] = "hello world";
my_strcpy(ch1,ch2);
printf("%s\n", ch1);
return 0;
}
```c
上面的图片中的内容应该是hello world\0我i写错了。
1.3 strcat(字符追加函数)
strcat函数是一个用于追加字符串的函数,即将一个字符串中的内容追加到另一个字符串后面(不会覆盖原字符串内容)。它的参数是两个指针,第一个指向的是追加字符串的目的地的起始位置,即要将字符串追加到什么地方;第二个指向的是要追加字符串的内容的起始位置,即需要追加的字符串。它的返回值是目标空间的起始位置。
char * strcat ( char * destination, const char * source );
int main()
{
char ch1[20] = "abcde";
strcat(ch1, "dfg");
printf("%s\n", ch1);
return 0;
}
strcat的模拟实现
char* my_strcat(char* p1, char* p2)
{
char* ret = p1;
while (*p1 != '\0')
{
p1++;
}
while (*p1++ = *p2++)
{
;
}
return ret;
}
int main()
{
char ch1[20] = "abcde";
my_strcat(ch1, "dfg");
printf("%s\n", ch1);
return 0;
}
首先经过第一个p1从a的地址经过while循环在遇到\0的时候跳出循环,来到如图中p1的位置,来到第二个循环,p把\0的位置覆盖掉,最后一直打印到\0停止循环。
1.4 strcmp(字符串比较函数)
int strcmp ( const char * str1, const char * str2 );
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
那么如何判断两个字符串?
int main()
{
char ch1[] = "abcde";
char ch2[] = "abq";
int ret = strcmp(ch1, ch2);
printf("%d\n", ret);
return 0;
}
他是根据对应的字符进行比较的。如下图,c的ASLL值小于q的ASLL的值,返回-1.
strcmp的模拟实现
int my_strcmp(char* p1, char* p2)
{
while (*p1++ == *p2++)
{
if (*p2 = '\0')
{
return 0;
}
}
if (*p1 > *p2)
{
return 1;
}
else
return -1;
}
int main()
{
char ch1[] = "abcde";
char ch2[] = "abq";
int ret = my_strcmp(ch1, ch2);
printf("%d\n", ret);
return 0;
}
strcpy,strcat,strcmp这些都是长度不受限制的字符串函数,在遇到\0之前会不停的打印。
而长度受限制的如strncpy,strncat,strcmp这些是可以受控制的,用法也是非常相似的。
char * strncpy ( char * destination, const char * source, size_t num );
char * strncat ( char * destination, const char * source, size_t num );
int strncmp ( const char * str1, const char * str2, size_t num );
拷贝num个字符从源字符串到目标空间。
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
这边就是他们的我写的一个简单的用法。
strstr(字符查找函数)
char * strstr ( const char *str1, const char * str2);
strstr函数可以在一个字符串(字符串1)中查找另一个字符串(字符串2),如果字符串2存在于该字符串1中,那么就返回被字符串2在字符串1中第一次出现的起始位置,如果在字符串1中找不到字符串2,那么就返回空指针(NULL)。它的第一个参数是字符串1的起始位置,第二个参数是字符串2的起始位置。
注意:
若字符串2为空字符串,则返回字符串1的起始位置。
举个例子,比如我们在字符串"abcdefbcd"中查找字符串"bcd"。
int main()
{
char ch1[] = "abcdefbcd";
char ch2[] = "bcd";
char*ret=strstr(ch1, ch2);
if (ret != NULL)
{
printf("%s\n",ret);
}
else
{
printf("找不到\n");
}
return 0;
}
他会找到b的地址,一直打印到\0结束。
注意:strstr函数的返回值是字符串"bcd"在字符串"abcdefbcd"中第一次出现的位置的起始位置,而不是出现几次就返回几个起始位置。
strstr的模拟实现
strstr模拟实现较为复杂。
2.模拟实现
strstr函数的模拟实现相对复杂,在实现过程中我们需要设置3个指针变量来辅助实现函数功能。
cp指针: 记录每次开始匹配时的起始位置,当从该位置开始匹配时就找到了目标字符串,便于返回目标字符串出现的起始位置;当从该位置开始没有匹配成功时,则从cp++处开始下一次的匹配。
p1和p2指针: 通过判断p1和p2指针解引用后是否相等来判断每个字符是否匹配成功,若成功,则指针后移比较下一对字符;若失败,p1指针返回cp指针处,p2指针返回待查找字符串的起始位置。
例如,在字符串"abbbcdef"中查找字符串"bbc":
刚刚开始时3个指针的指向如图所示
cp代表a的地址,p1现在也在a的位置上,p2在p的位置上。
p1!=p2,cp向右移动一个位置。
cp向右移动一个位置,使p1=cp,这时候p1=b,p2也等于b,p1继续移动,p1=b,
p2=b,p1=p2,继续移动,p1=b,p2=c,p1!=p2,移动cp的位置,变成如图中的位置
cp向右移动一个位置,然后p1=cp,p1=b,p2回到原始点,继续比较,一直到\0,p2就会停止。大体思路就是这样。
char* my_strstr(char* str1, char* str2)
{
char* p1 = str1;
char* p2 = str2;
char* cp = str1;
while (*cp)
{
p1 = cp;
p2 = str2;
while (*p1 == *p2)
{
p1++;
p2++;
}
if (*p2 == '\0')
{
return cp;
}
cp++;
}
return NULL;
}
int main()
{
char ch1[] = "abcdefbcd";
char ch2[] = "bcd";
char* ret = my_strstr(ch1, ch2);
if (ret != NULL)
{
printf("%s\n", ret);
}
else
{
printf("找不到\n");
}
return 0;
}
最后一个就是 strtok(字符分割函数)
char * strtok ( char * str, const char * sep )
strtok函数能通过给定的一系列字符将一个字符串分割成许多子字符串的函数。它的第一个参数是需要被分割的字符串的首地址;第二个参数是一个字符串的首地址,该字符串是用作分隔符的字符集合。返回值是查找到的标记的首地址。
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
int main()
{
char ch[] = "[email protected]";
char* p = "@.";
char buffer[30] = { 0 };
strcpy(buffer,ch);
char*ret=strtok(buffer, p);
printf("%s\n", ret);
ret = strtok(NULL, p);
printf("%s\n", ret);
ret = strtok(NULL, p);
printf("%s\n", ret);
return 0;
}
这样写太麻烦,可以换一种写法
int main()
{
char ch[] = "[email protected]";
char* p = "@.";
char buffer[50] = { 0 };
strcpy(buffer, ch);
char* ret = NULL;
for (ret = strtok(buffer, p); ret != NULL; ret = strtok(NULL, p))
{
printf("%s\n", ret);
}
return 0;
}
好了今天的内容大概就是这么多。
标签:p2,字符,p1,函数,int,ret,char,字符串 From: https://blog.csdn.net/2402_82552926/article/details/143453839