字符串函数的使用及模拟实现

简介: 字符串函数的使用及模拟实现

一:strstr函数的使用

strstr是在一个字符串中寻找子字符串

功能:返回str2在str1第一次出现的位置

如果没出现,就返回NULL

#include <stdio.h>
#include <string.h>
int main()
{
  char str1[] = "abcdefg";
  //char str2[] = "cde";
  char str2[] = "cdc";//str1找不到cdc返回 null
    char *s=strstr(str1, str2);//在str1中寻找str2,并返回第一次str2在str1出现的位置
  printf("%s\n", s);//cdefg
  return 0;
}

strstr的模拟实现

设置一个指针cp,表示可能str1中找到str2的地址,便于打印

设置一个指针s2 ,表示每次寻找时str2的首字符地址。

设置一个指针s1,表示每次寻找时,str1的地址

#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
  assert(str1 && str2);
  if (*str2 == '\0')//规定如果str2为""返回str1的值
  return str1;
  char* cp = str1;//用cp遍历str1中可能符合要求的地址,从str1的首字符到最后一个字符'\0'
  //后面返回cp,便于打印
  char* s1 = NULL;
  char* s2 = NULL;
  while (*cp)
  {
    s1 = cp;
    s2 = str2;//每次遍历前用s2代表str2的首字符的地址
    while (*s1 == *s2&&*s1)//&&*s1表示*s1和*s2均不等于'\0'
    {
      s1++;
      s2++;
    }
    if (*s2 =='\0')//当*s2='\0'时,说明s2从首字符遍历到了最后一个字符'\0'
    {
      return cp;//
    }
    cp++;//当cp为str1的手字符时,不符合要求,cp++,表示cp在str1的地址向后一个元素
  }
   return NULL;//当*cp='\0'时,说明在str1中找不到str2,返回null
}
int main()
{
  char str1[] = "abcdef";
  char str2[] = "abcdef";
  char *s=my_strstr(str1, str2);
  if (s != NULL)
    printf("%s\n", s);
  else
    printf("找不到\n");
  return 0;
}

二:strncpy的使用及模拟使用

strncpy的使用

与strcpy最大的区别就是 规定了拷贝的长度,

#include <stdio.h>
#include <string.h>
int main()
{
  char a1[] = "abcdedf";
  char a2[10] = "xxx";
  char* s = strncpy(a2, a1,5);//a2从a1中拷贝了5个字节
  printf("%s\n", s);//abcde
  return 0;
}

strncpy的模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* a2, const char* a1, size_t width)
{
  assert(a2 && a1);
  char* start = a2;
  while (width--)//每拷贝一次拷贝长度-1
  {
    *a2 = *a1;//实现拷贝
    a2++;
    a1++;
  }
  return start;
}
int main()
{
  char a1[] = "abccdefg";
  char a2[10] = { 0 };
  printf("%s\n",my_strncpy(a2, a1, 4));
  return 0;
}

可能有同学疑问,strncpy拷贝过程中并没有拷贝’\0’,为什么编译器没有报错,而是打印了我们想要的结果呢?

哈哈,我们想一块去了,虽然strncpy拷贝过程中并没有拷贝’\0’,但我们给a2初始化了10个’\0’.

三:strncat的使用及模拟实现

strncat的使用

与strcat函数相似,只是规定了追加的长度,可能不是追加了一个字符数组

#include <stdio.h>
#include <string.h>
int main()
{
  char a1[20] = "hello ";//未初始化的元素全部是'\0'
  char a2[] = "world!!!";
  strncat(a1, a2,6);//将a2中的6个元素追加到a1中
  printf("%s\n", a1);
  return 0;
}

strncat的模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strncat( char* a1,const char* a2, size_t width)
{
  assert(a1 && a2);
  char* start = a1;
  while (*a1 != '\0')
  {
    a1++;
  }//*a1='\0'时开始追加
  while (width--)
  {
    //a2追加到a1上
    *a1 = *a2;
    a1++;
    a2++;
  }
  return start;//返回a1的首元素的地址,便于链式访问
}
int main()
{
  char a1[20] = "hello ";
  char a2[] = "world!!!!!!!!!!!!!!!!";
  //链式访问
  printf("%s\n", my_strncat(a1, a2, 7));
}

四:strtok的使用

今天是2023年9月10日,可以写成2023.9.10我们可以得到2023

9

10

吗?

strtok函数就可以实现

#include <stdio.h>
#include <string.h>
int main()
{
  char a[] = "2023.9.10";
  char b[10] = { 0 };
  strcpy(b, a);//strtok函数分割的一般是临时拷贝的内容,并且可以修改
  char* p = ".";//p参数指向一个字符串,定义了用作分隔符的集合
  char* s=strtok(b, p);//字符指针用于存储字符串,s指向字符串首字符的地址
  //strtok的第一个参数不为NULL,函数将找到b中的第一个标记 . strtok并将保存它在字符串中的位置
  printf("%s\n", s);
  s=strtok(NULL, p);
  //第二次传NULL,就表示接着上次找,也就是从  . 后面的地址开始找
  printf("%s\n", s);
  s=strtok(NULL, p);//同第二次调用同理
  //如果字符串中没有标记了,则返回NULL指针
  printf("%s\n", s);
  return 0;
}

上面的代码比较笨,如果分隔符多了,就会使代码变得非常繁琐,下面使用循环的方法,能达到更好的效果。

```c
#include <stdio.h>
#include <string.h>
int main()
{
  char a[] = "2023.9.10";
  char b[20] = { 0 };
  char* p = ".";
  char* r = NULL;
  strcpy(b, a);
  //如果字符串中没有标记了,则返回NULL指针,也就结束了循环
  for (r = strtok(b, p); r != NULL; r = strtok(NULL, p))
  {
    printf("%s\n", r);
  }
  return 0;
}

五:strerror函数的使用

strerror可以把参数部分的错误码对应的错误信息的字符串地址返回来,strerror函数的使用需要头文件string.h

错误码一般放在errno.h这个头文件中说明的。

当库函数调用失败的时候,会讲错误码记录到errno这个变量中

errno是一个C语言的全局变量。



目录
相关文章
|
22天前
(一)字符函数和字符串函数详细讲解和模拟实现(优化)
(一)字符函数和字符串函数详细讲解和模拟实现(优化)
|
22天前
(二)字符函数和字符串函数详细讲解和模拟实现(优化)
(二)字符函数和字符串函数详细讲解和模拟实现(优化)
|
1月前
|
安全
16.字符串函数的使用和模拟实现(全)
16.字符串函数的使用和模拟实现(全)
|
2月前
字符串函数的模拟实现
字符串函数的模拟实现
22 1
|
2月前
|
C语言
字符函数和字符串函数解析及模拟实现
字符函数和字符串函数解析及模拟实现
52 0
|
7月前
|
程序员
字符串函数的使用及其模拟实现
字符串函数的使用及其模拟实现
39 0
|
9月前
|
C语言 C++
C/C++字符函数和字符串函数详解————内存函数详解与模拟
C/C++字符函数和字符串函数详解————内存函数详解与模拟
30 1
|
12月前
|
C语言
深入探索字符串函数与模拟实现
深入探索字符串函数与模拟实现
81 1
深入探索字符串函数与模拟实现
字符函数和字符串函数的使用及模拟实现(上)(2)
字符函数和字符串函数的使用及模拟实现
71 0

热门文章

最新文章

  • 1
    流量控制系统,用正则表达式提取汉字
    25
  • 2
    Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
    26
  • 3
    Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
    25
  • 4
    Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
    27
  • 5
    S外部函数可以访问函数内部的变量的闭包-闭包最简单的用不了,闭包是内层函数+外层函数的变量,简称为函数套函数,外部函数可以访问函数内部的变量,存在函数套函数
    23
  • 6
    Redis06-Redis常用的命令,模糊的搜索查询往往会对服务器产生很大的压力,MSET k1 v1 k2 v2 k3 v3 添加,DEL是删除的意思,EXISTS age 可以用来查询是否有存在1
    30
  • 7
    Redis05数据结构介绍,数据结构介绍,官方网站中看到
    21
  • 8
    JS字符串数据类型转换,字符串如何转成变量,+号只要有一个是字符串,就会把另外一个转成字符串,- * / 都会把数据转成数字类型,数字型控制台是蓝色,字符型控制台是黑色,
    19
  • 9
    JS数组操作---删除,arr.pop()方法从数组中删除最后一个元素,并返回该元素的值,arr.shift() 删除第一个值,arr.splice()方法,删除指定元素,arr.splice,从第一
    19
  • 10
    定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
    19