征服C语言字符串函数(超详细讲解,干货满满)(下)

简介: 征服C语言字符串函数(超详细讲解,干货满满)

1.3.3. 问题回答

字符串自己给自己追加的话:

假设字符串char arr[20]="abcd"给自己追加
strcat(arr,arr);
我们先把隐藏的'\0'写出来
"abcd\0"
第一步找到目标字符串的'\0'
第二步进行逐步赋值,直到源头字符串src找到'\0'为止
"abcda"
注意到仅仅只进行了一次赋值,'\0'就被'a'给覆盖了,也就是说源头字符串src将永远无法找到'\0',所以
:
如果字符串自己给自己追加的话,'\0'会被覆盖,所以循环会变为死循环

所以一定不能自己给自己追加,否则程序会崩溃

1.4. strcmp

strcmp:字符串比较函数

1.4.1 strcmp函数剖析

C语言标准规定:
int strcmp ( const char * str1, const char * str2 );
字符串比较函数strcmp:
依次比较两个字符串str1与str2对应位置的ascii码值
1.如果相同,则str1++,str2++,进行下一个位置元素的比较
2.如果最终两者相同,则返回0
3.如果str1 > str2:返回大于0的数字
4.如果str1 < str2:返回小于0的数字
假设str1 = "abcd"
str2 = "abde"
str3 = "abc"
则str1与str2的'a'与'b'均相同,跳过,到达'c'和'd'之后,因为'c'的ASCII码值小于'd',所以返回<0的数字
str1与str3的'a'和'b'和'c'均相同,到达'd'和'\0'之后,因为'd'的ASCII码值大于'\0',所以返回>0的数字
注意:'\0'的ASCII码值是最小的,为0
在VS编译器上:
2.如果最终两者相同,则返回0
3.如果str1 > str2:返回1
4.如果str1 < str2:返回-1
英语好的老铁可以看一下
This function starts comparing the first character of each string. 
If they are equal to each other, it continues with the following pairs until the characters differ or until a terminatingnull-character is reached.

1.4.2 strcmp函数模拟实现

int my_strcmp(const char* str1, const char* str2)
{
  assert(str1 != NULL);
  assert(str2 != NULL);
  while (*str1 == *str2)
  {
    str1++;
    str2++;
  }
  return *str1 - *str2;
}
int main()
{
  char arr1[] = "acdf";
  char arr2[] = "an";
  int ret = my_strcmp(arr1, arr2);
  printf("%d", ret);//返回<0的数字,因为'c'<'n'
  return 0;
}

1.5. strstr

strstr:字符串查找函数

1.5.1 strstr函数剖析

char * strstr ( const char *str1, const char * str2);
Returns a pointer to the first occurrence of str2 in str1,
or a null pointer if str2 is not part of str1.
返回str2在str1里出现的对应的str1中"首"元素的地址
假设:str1="abbbcde",str2="bbcde"
也就是说返回str1中第二个'b'的位置

1.5.2 strstr函数模拟实现

这里采用BF暴力算法:

char* my_strstr(const char* str1, const char* str2)
{
  char* cp = str1;
  char* s1 = cp;
  char* s2 = str2;
  while (*cp)
  {
    while (*s1 && *s2 && *s1 == *s2)
    {
      s1++;
      s2++;
    }
    if (*s2 == '\0')
      return cp;
    else if (*s1 == '\0')
      return NULL;
    else
    {
      cp++;
      s1 = cp;
      s2 = str2;
    }
  }
  return NULL;
}
具体思想是:
1.先用cp,str2作为标志位,
进行匹配时:
1.如果s1与s2对应位置的字符相同,则s1与s2均后移
直到*s1为'\0',或*s2为'\0',或s2与s1的对应位置的字符不同退出while循环,
当退出while循环后如果*s2为'\0',则表示匹配成功,返回cp
2.如果s1与s2对应位置的字符不同,则cp后移,s1退到cp,s2退到str2,再进行匹配,如果cp指向了'\0'时还没有匹配成功
也就意味着已经彻底匹配失败了,返回NULL
3.如果退出时是因为*s1为'\0',则表示彻底匹配失败,返回NULL

下面请大家看一下具体实现流程

1.6 strtok

字符串切割函数

1.6.1 strtok函数剖析

char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标
记。
1.strtok函数找到str中的下一个标记,并将其用 '\0' 结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
2.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
3.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
4.如果字符串中不存在更多的标记,则返回 NULL 指针。
从中可以看出strtok具有记忆性

演示:

int main()
{
  char arr[] = "helloworld@yeah.net";
  char copy[30];
  strcpy(copy, arr);
  char sep[] = "@.";
  char* ret = strtok(copy, sep);
  printf("%s\n", ret);//helloworld
  ret = strtok(NULL, sep);
  printf("%s\n", ret);//yeah
  ret = strtok(NULL, sep);
  printf("%s\n", ret);//net
  return 0;
}
这里还可以用for循环来简化代码
int main()
{
  char arr[] = "helloworld@yeah.net";
  char copy[30];
  strcpy(copy, arr);
  char sep[] = "@.";
  char* ret = NULL;
  因为ret只需设置为strtok(copy,sep)一次,所以可以考虑作为for循环的初始条件
  其余所有调用都只需要传NULL,sep即可,所以考虑作为for循环的更新条件
  当ret为NULL时,切割成功完成,所以可以作为for循环的终止条件
  for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep))
  {
    printf("%s\n", ret);
  }
  return 0;
}

二.有长度限制的字符串函数

上面的strcpy,strcat,strcmp函数都是需要找到’\0’的字符串,也就是如果找不着’\0’会继续向下找,所以不安全(可能会出现越界访问的情况)

所以接下来我们介绍一下三个有长度限制的函数:

strncpy

strncat

strncmp

2.1. strncpy

char * strncpy ( char * destination, const char * source, size_t num );
Copies the first num characters of source to destination. 
If the end of the source C string(which is signaled by a null-character) 
is found before num characters have been copied,
destination is padded with zeros until a total of num characters have been written to it.
1.拷贝num个字符从源字符串到目标空间。
2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加'\0',直到num个。
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "xxx";
  strncpy(arr1, arr2, 2);
  printf("%s\n", arr1);//xxcdef
  return 0;
}

2.2. strncat

char * strncat ( char * destination, const char * source, size_t num );
Appends the first num characters of source to destination, plus a terminating null-character.
If the length of the C string in source is less than num,
only the content up to the terminating null-character is copied.

将源代码的第一个num字符附加到目标代码中,再加上一个终止的’\0’

如果源代码中的C字符串的长度小于num,则只复制直到终止的空字符的内容。

int main()
{
  char arr1[30] = "abcd";
  char arr2[] = "efgh";
  //strncat(arr1, arr2, 4);
  //printf("%s\n", arr1);//abcdefgh
  //strncat(arr1, arr2, 2);
  //printf("%s\n", arr1);//abcdef
  strncat(arr1, arr1, 4);
  printf("%s\n", arr1);//abcdabcd
  由此可见,我们可以通过strncat函数来让arr1:"abcd"变为"abcdabcd"
  实现"翻倍"
}

2.3. strncmp

int strncmp ( const char * str1, const char * str2, size_t num );
只比较num个字符来返回比较结果
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "abdcdef";
  int ret = strncmp(arr1, arr2, 2);
  printf("比较前两个字符:%d\n", ret);//0
  ret = strncmp(arr1, arr2, 3);
  printf("比较前三个字符:%d\n", ret);//-1
  int len1 = strlen(arr1);
  int len2 = strlen(arr2);
  ret = strncmp(arr1 + len1 - 3, arr2 + len2 - 3, 3);
  printf("比较后三个字符:%d\n", ret);//0
}

以上就是字符串函数专题的讲解,希望能给大家带来帮助,谢谢大家.

相关文章
|
1月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
26天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
22 0
|
1月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
1月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
1月前
|
C语言
【C语言】模拟实现深入了解:字符串函数
【C语言】模拟实现深入了解:字符串函数
|
3月前
|
安全 程序员 C语言
【C语言】字符串函数及其模拟实现
【C语言】字符串函数及其模拟实现
|
3月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
63 0
|
3月前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
55 0
|
4月前
|
存储 缓存 C语言
【C语言】字符函数,字符串函数,内存函数
C语言中的字符串函数和内存函数
57 0
【C语言】字符函数,字符串函数,内存函数
|
5月前
|
C语言
【c语言】字符串函数的模拟实现(二)
【c语言】字符串函数的模拟实现(二)
26 1