字符和字符串函数2
上节内容讲的3个函数是没有长度限制的,拷贝和追加的过程中会有溢出的风险。有没有优化的版本呢?答案是有的。
//有源字符串长度限制
strncopy
strncat
strncmp
strncopy
函数与上节内容讲的类似,唯一不同的地方就是有了长度限制,追加完,拷贝完自动在字符串末尾加\0。
int main()
{
char ch[] = "************";
char* ch1 = "abc";
strncpy(ch, ch1, 2);
printf("%s\n", ch);
return 0;
}
如果 src 的长度小于 n,strncpy 会在复制完 src 的所有字符后,向 dest 中填充 ‘\0’ 直到总长度达到 n。但如果 src 的长度大于或等于 n,dest 中将不会自动添加终止符,此时 dest 可能不是一个以 ‘\0’ 结尾的有效 C 字符串。
strncat
字符串追加函数,但是这个函数可以自己给自己追加,因为它会自动在追加完n个数据后增加\0。
#include<string.h>//可以给自己追加内容,追加完自动在末尾加'\0'
int main()
{
char ch1[20] = "abcd";
char *ch2 = "efghz";
strncat(ch1, ch1,4);
printf("%s\n", ch1);
return 0;
}
找到目标字符串的末尾:strncat 会首先找到 dest 中第一个 ‘\0’ 终止符的位置,从该位置开始追加 src 的内容。
追加字符:将 src 中的字符追加到 dest 的末尾,直到追加了 n 个字符或遇到 ‘\0’ 终止符。
自动添加终止符:无论 src 的长度如何,strncat 都会在追加完成后,在 dest 的末尾添加一个 ‘\0’ 终止符。因此,dest 始终是一个以 ‘\0’ 结尾的有效 C 字符串。
strncmp
比较函数,用于比较前n个数据的大小。
int main()
{
const char* ch1 = "abcde";
const char* ch2 = "abcdr";
int r = strncmp(ch1, ch2,4);
printf("%d\n", r);
return 0;
}
逐字符比较:strncmp 会逐个比较 s1 和 s2 的字符,直到:
比较了 n 个字符;
遇到不相等的字符;
遇到 ‘\0’ 终止符。
终止条件:
如果在比较到第 n 个字符之前遇到了 ‘\0’ 终止符,则比较提前结束。例如,若 s1 是 “abc”,s2 是 “abcd”,当 n >= 4 时,strncmp(s1, s2, n) 会返回负值(因为 s1 的长度更短)。
如果比较了 n 个字符都相等,则返回 0。
strtok函数
作用:用来分离含有标记的字符串。
啥意思?1234@qq.com$$123
这个函数就会把特殊字符作为标记,将其左右的内容分离出来。
函数char * strtok ( char * str, const char * sep);
使用 strtok 函数时需注意以下要点:
- sep 参数用于指定分隔符集合,其值为一个字符串
- 第一个参数为待分割的字符串,其中包含零个或多个由 sep 中分隔符分割的标记
- strtok 会查找字符串中的下一个标记,将其以 \0 结尾,并返回指向该标记的指针(注意:strtok 会修改原字符串,因此通常使用可修改的临时副本)
- 当第一个参数非 NULL 时,函数将查找字符串中的第一个标记,并保存其在字符串中的位置
- 当第一个参数为 NULL 时,函数将从上次保存的位置开始查找下一个标记
- 若字符串中无更多标记,函数将返回 NULL 指针
也就是说该函数的返回值是标记前的字符串的第一个字符的地址。
#include<string.h>
int main()
{
char ch[] = "1780163243@qq.com";
char buf[30] = { 0 };
strcpy(buf, ch);
char* p = "@ .";
char* s = strtok(buf, p);//返回的是第一个标记符之前的第一个字符地址
printf("%s\n", s);
s = strtok(NULL, p);//字符指针重新赋值
printf("%s\n", s);
s = strtok(NULL, p);//字符指针重新赋值
printf("%s\n", s);
return 0;
}
#include<string.h>
int main()
{
char ch[] = "1780163243@qq.com";
char buf[30] = { 0 };
strcpy(buf, ch);
char* p = "@ .";
char* r = NULL;
for (r = strtok(buf, p); r != NULL;r=strtok(NULL,p))
{
printf("%s\n", r);//不存在标记,返回NULL
}
return 0;
}
//第一次返回1的地址,第二次返回q的地址,第三次返回c的地址,第四次返回NULL
这段代码也很好的诠释了上述内容。
strstr函数
这个函数的作用是第一个字符串里面找出第二个字符串,并返回其首位字符的位置。包含string.h
#include<string.h>
int main()
{
char str[] = "this is a apple";
char* ch;
ch = strstr(str, "apple");
strncpy(ch, "bbbb", 3);
printf("%s\n", ch);
return 0;
}
运行结果:bbble
模拟实现

char* my_strstr(const char* str1, const char* str2)
{
const char* c = str1;
const char* p1 = NULL;
const char* p2 = NULL;
if (*str2 == '\0')
{
return str1;
}
while (*c)
{
p1 = c;
p2 = str2;
while (*p1 == *p2 && *p2 && *p1)
{
p1++;
p2++;
}
if (*p2 == '\0')
{
return c;
}
c++;
}
return NULL;
}
int main()
{
char str[] = "this is a apple";
char* ch;
ch = my_strstr(str, "apple");
printf("%s\n", ch);
return 0;
}
思路定义三个指针,其中c指向开始遍历字符串的起始位置,交给p1,p2去便利,遍历成功返回c,否则返回NULL。
更多推荐
所有评论(0)