深度剖析C语言中字符串函数的坑点与细节,并且总结归纳
一.字符串函数
在 C 语言中,包含 string.h 这个头文件的库函数有不少,而且用起来也很便捷,但其中有坑的东西也不在少数,所以,我向大家来介绍一下这个头文件中好用的函数与需要注意的地方
1.字符串拷贝函数
strcpy字符串拷贝函数,将后面的字符串拷贝到前面的字符串,遇见\0停止
这个函数的形式如下
char * strcpy (char *dest,const char * src)
返回值是 char*,也就是说,这个函数会返回一个字符串指针,参数有两个,都是 char*类型的,代表了接收类型只有字符串指针类型,而且注意到,第二个指针前加了 const,而且还是在解引用操作符之前,这代表了,src 指向的内容不可被修改(但是可以修改 src 指向的对象,这是关于指针的内容,如果有不熟悉的可以去翻一下我写指针的博客),那么这样做是为什么呢?可以借助于这两个指针的名字来更好的理解,destination(目的地),source(源头),其意思就是将源头的内容放到目的地里,那既然我们要做到完整的 copy,那么src 的内容我们是不希望被修改的,所以加上 cosnt 修饰,这样一来,我们就能够完整的了解到这个函数了
我给出这个代码的实现
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);
//1.找到目标空间中的\0
while (*dest != '\0')
{
dest++;
}
//2.数据的拷贝
while (*dest++ = *src++)
{
;
}
return ret;
}
2.字符串拼接函数
trcat 字符串拼接函数,将后面的字符串移到前面的字符串的\0后拼接,直到\0停止
char * strcat (char * dest,const char *src)
这个函数可以理解为将 源头 src 的字符串拷贝到目的地 dest 的字符串\0之后的位置
同样我也给出代码实现
char * my_strcat(char *dest,const char *src)
{
assert(dest && src);
char *ret = dest;
//找到目标位置的\0
while(*dest != 0)
{
dest++;
}
//赋值运算
while(*dest++ = *src++)
;
return ret;
}
相信大家看到了这两个的代码实现之后,会有一种一头雾水或者叹为观止的感觉
while(*dest ++ = *src ++)
在我刚接触到这串代码时,我也是直呼牛逼,让我们来剖析
while循环语句,判断条件为真假,在 C/C++语言中,0 表示假,非 0 表示真,所以当*scr 为 0 时,while 结束,所以当源头的字符串拷贝完遇到了\0,将这些值都赋值给了 dest,循环就结束了,而这里也用到了++单目操作符,后置++,先进行使用,再进行++,这样以来,就可以将所有\0之前的字符都进行拷贝和拼接;
3.字符串比较函数
strcmp函数,比较字符串\0之前的大小
而且这种比较是看对应字符的ASIC 码值
int strcmp (const char * str1,const char * str2)
当 *str1 > *str2 的时候,会返回 大于 0 的数
当 *str1 < *str2 的时候,会返回小于 0 的数
当*str1 = *str2 的时候,会返回 0
以下是函数的实现
int my_strcmp(const char *str1,const char *str2)
{
assert(str1 && str2);
while(*str1 == *str2)
{
if(*str1 == 0)
{
return 0;
}
str1++;
str2++;
}
if(*str1>*str2) return 1;
if(*str2>*str1) return -1;
}
以上的函数,都有 strn 版本例如,strncpy,strncmp,strncat,这个三个函数可以指定字符串的大小只需要在两个指针参数后跟上要比较的数量就可以了
4。字符串查找子串函数
char * strstr (const char *str1, cosnt char *str2)
这个 strstr 函数可以在寻找字符串子串,而子串的意思是str2 的这个字符串在 str1 中第一次出现的位置,并返回这个字符串的地址
再次给出实现
char * my_strstr(const char* str1,const char * str2)
{
//暴力查找法
const char *s1 = NULL;
const char *s2 = NULL;
const char *cur = str1;
while(*cur)
{
s1 = cur;
s2 = str2;
while(*s1 != 0 && *s2 != 0 && *s1 == *s2)
{
s1++;
s2++;
}
if(*s2 == 0)
return (char *)cur;
cur++;
}
return NULL
在这里,我简单的讲一下查找逻辑,因为返回的是首次找到子串的地址,所以要有一个指针来标记子串,而另外两个指针来匹配字符串的内容,因为当标记指针是 0 时,也就代表已经遍历完了整个被查找字符串,而且不知道循环的次数,所以用 while 循环,进入循环,开始匹配,如果两个字符相等就往后查询,如果不想等,那么标记就需要往后走,再次匹配,当被查找字符串走到\0时,也就代表着已经找到了子串,返回标记的地址。
以上是查找逻辑,为暴力查找,如果要提升性能,可以用 kmp 算法来优化,有兴趣的可以了解一下。
5.分隔字符串函数
strtok,这个函数可以用来分隔一些字符串的内容
char * strtok ( char * str, const char * delimiters );
这个函数可以用来分隔一些字符串,比如邮箱号
d2025440304@gmail.com
就可以将@和.分隔的三个部分提取出来
d2025440304
gmail
com
而这个函数的使用逻辑是,找到了第一个分隔符,比如@,下次使用时第一个指针就要传为空指针,而第二个就是分隔符指针,如下
#include <string.h>
int main()
{
char arr[] = "daixiangyu@2007.0304";
char arr2[] = {0};
strcpy(arr2,arr);
const char *sep = "@.";
char *ret =NULL;
for(ret = strtok(arr2,sep);ret!=NULL;ret = strtok(NULL,sep))
{
printf("%s\n",ret);
}
return 0;
}
这样利用 for 循环的方式,就可以巧妙的将三个分隔符的内容分别打印出来
好了,已上就是字符串函数的内容所有精华,如有不妥与,请各位指教
谢谢大家
更多推荐
所有评论(0)