库函数之字符函数与字符串函数(下)

简介: 库函数之字符函数与字符串函数(下)

一、strncpy函数,strncat函数,strncmp函数


头文件:#include <string.h>


看过上一篇的小伙伴们都知道,对于下列函数应该都有所了解.


strcpy函数:.拷贝字符串函数


strcat函数:.追加字符函数


strcmp函数:.字符串拷贝函数


这些函数在使用时,都是遇到’\0’,才停止他们的拷贝,追加,比较等操作


如果我们想要只操作其中的部分,就可以增加一个参数来实现.


由于功能参数等与前面的函数相似,本篇不做重点讲解.


函数作用


strncpy函数


拷贝num个字符从源字符串到目标空间


strncat函数


追加num个源字符到目标空间


strncmp函数


比较两个字符串的前num个字符,返回值与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 );


参数介绍


增加一个size_t 类型的参数num,用于限定原来的函数.


模拟实现strncpy


#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* strDest, const char* strSource, size_t count)
{
  assert(strDest);
  assert(strSource);
  char* ret = strDest;
  while (count--)
  {
    *strDest++ = *strSource++;
  }
  return ret;
}
int main()
{
  char arr1[20] = "xxxxxxxxxxxxxx";
  char arr2[] = "Hello CSDN!";
  int sz2 = sizeof(arr2) / sizeof(arr2[0]);
  printf("%s", my_strncpy(arr1,arr2,5));
  return 0;
}


运行结果:


Helloxxxxxxxxx


注意:


1.strncpy只拷贝num个字符,并不会额外附加’\0’字符.


2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个.


这个在模拟的时候并没有添加上去.


模拟实现strncat函数


#include <stdio.h>
#include <assert.h>
char* my_strncat(char* destination, const char* source, size_t num)
{
  assert(destination);
  assert(source);
  char* ret = destination;
  while (*destination != '\0')
  {
    destination++;
  }
  while (num--)
  {
    *destination++ = *source++;
  }
  return ret;
}
int main()
{
  char arr1[20] = "Hello ";
  char arr2[] = "CSDN!";
  int sz2 = sizeof(arr2) / sizeof(arr2[0]);
  printf("%s", my_strncat(arr1, arr2, 3));
  return 0;
}


运行结果:


Hello CSD


模拟实现strncmp函数


#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* str1, const char* str2, size_t num)
{
  while (num--)
  {
    if (*str1 > *str2)
    {
      return 1;
    }
    else if (*str1 < *str2)
    {
      return -1;
    }
    str1++;
    str2++;
  }
  return 0;
}
int main()
{
  char arr1[20] = "aabbccdd";
  char arr2[] = "aabbcdef";
  int sz2 = sizeof(arr2) / sizeof(arr2[0]);
  printf("%d", my_strncmp(arr1, arr2, 5));
  return 0;
}


运行结果:


0


解释:


因为前5个字符相同,num个字符比较结束,认为是相同字符串.


二、strstr函数


strstr函数


头文件:#include <string.h>


函数参数模型



函数作用:


用于查找主字符串中是否包含子字符串.包含返回第一次匹配成功的字符首地址.不包含则返回NULL.


函数的应用


力扣------找出字符串中第一个匹配的下标.


通过strstr函数找到第一个匹配的字符指针,


该指针-字符串首地址指针=该字符的下标.


int strStr(char * haystack, char * needle){
    char*ret=strstr(haystack,needle);
    if(ret-haystack<0)//小于0时,返回-1;
    {
        return -1;
    }
    return ret-haystack;
}


模拟实现


  1. 创建三个指针


  1. p1指向主字符串首地址,p2指向子字符串首地址.


  1. ret用于保存p1回退的位置.


  1. 当*p1==p2时,p1和p2继续向后比较,当p1!=*p2时,说明ret位置不对,则ret++


  1. p1退回到ret位置,p2回到初始位置,重新比较.


  1. 直到p2指向’\0’,则匹配成功,p1指向’\0’则匹配失败.



动图解析:



代码实现:


#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
  assert(str1 && str2);
  if (*str2 == '\0')//如果子字符串是空字符串,直接返回主字符串
  {
    return str1;
  }
  const char *ret,*p1,*p2;
  ret = p1 = str1;
  p2 = str2;
  while (*p1&&*p2)//循环停止条件为主字符串或者子字符串有一个为空
  {
    if (*p1 == *p2)//相等则继续比较
    {
      p1++;
      p2++;
    }
    else//不相等则返回指定位置重新比较
    {
      p1 = ++ret;
      p2 = str2;
    }
  }
  if (*p2 == '\0')//如果子字符串比较结束,则匹配成功
  {
    return ret;
  }
  else//否则匹配失败
    return NULL;
}
int main()
{
  char str1[20] = "ABBCDABBACBBD";
  char str2[] = "ABBA";
  char* ret = my_strstr(str1, str2);
  if (ret == NULL)
  {
    printf("没有找到\n");
  }
  else printf("%s", ret);
}


ABBACBBD


三、strtok函数


strtok函数


头文件:#include <string.h>


函数参数模型


strtok函数



函数作用:


将字符串str根据delimiters 中的字符进行分割.


参数介绍:


参数 意义
str 需要被分隔的字符串(第一次传参的时候),传入NULL指针时,会从上一次修改的地址处
delimiters 定义了用作分隔符的字符集合


函数应用


#include <stdio.h>
#include <string.h>
int main()
{
  char str1[30] = "123.456.789_111,222@333";
  char str2[30];
  char a[] = "._,@";
  strcpy(str2, str1);//因为strtok函数会改变传过去的字符串的内容,所以我们是将备份传过去
  char* ret;
  //除了第一次调用时第一个参数为str2以外,后面的调用都是传入NULL,这样才会继续向后寻找标记分隔字符.
  for (ret = strtok(str2, a); ret != NULL; ret = strtok(NULL, a))
  {
    printf("%s\n", ret);
  }
  return 0;
}


运行结果:


123


456


789


111


222


333


strtok函数注意事项:


strtok函数并不是一次就将字符串中的所有分隔字符改为’\0’,而是调用它一次,修改一个.


strtok函数第一次调用时,会找到str中的第一个分隔符标记,并将其用 \0 结尾,然后返回一个指向这个标记的指针。


strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。:


strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。


strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。


如果后面已经没有标记分隔,则返回 NULL 指针.


四、strerror函数


sterror函数



函数作用


库函数在使用错误时,会返回一串数字,这些数字就是错误码.


strerror函数用于返回错误码对应的错误信息.


例如:


#include <stdio.h>
#include <string.h>
int main()
{
  printf("%s\n", strerror(0));
  printf("%s\n", strerror(1));
  printf("%s\n", strerror(2));
  printf("%s\n", strerror(3));
  printf("%s\n", strerror(4));
  printf("%s\n", strerror(5));
  return 0;
}


No error


Operation not permitted


No such file or directory


No such process


Interrupted function call


Input/output error


但是strerror函数并不是这样使用的,因为我们也不知道错误码是什么,像上面这种是属于提前预判了的.


在库函数执行错误后,会将错误码存放在一个error的变量中.所以一般strerror函数是这样使用的.


函数应用


#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
  //打开文件
  FILE* pf = fopen("CSDN.txt", "r");
  if (pf == NULL)
  {
    //printf("%s\n", strerror(errno));
    perror("fopen");
    return 1;
  }
  //关闭文件
  fclose(pf);
  pf = NULL;//避免空指针
  return 0;
}


perror函数等价于printf(“%s\n”, strerror(errno));


即strerror函数是返回指向错误信息的字符串地址,而perror函数是将错误信息直接打印出来.


希望这篇文章能帮助大家对c语言中的库函数有关字符函数和字符串函数有更深层的理解.

目录
相关文章
|
8天前
|
云安全 人工智能 算法
以“AI对抗AI”,阿里云验证码进入2.0时代
三层立体防护,用大模型打赢人机攻防战
1401 10
|
8天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1268 6
|
9天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
1117 14
|
3天前
|
人工智能 前端开发 API
Google发布50页AI Agent白皮书,老金帮你提炼10个核心要点
老金分享Google最新AI Agent指南:让AI从“动嘴”到“动手”。Agent=大脑(模型)+手(工具)+协调系统,可自主完成任务。通过ReAct模式、多Agent协作与RAG等技术,实现真正自动化。入门推荐LangChain,文末附开源知识库链接。
399 118
|
6天前
|
存储 缓存 NoSQL
阿里云经济型e实例(ecs.e-c1m4.large)2核8G云服务器优惠活动价格及性能测评
阿里云经济型e实例(ecs.e-c1m4.large)2核8G配置,支持按使用流量或按固定带宽两种公网计费方式,搭配20G起ESSD Entry云盘,是主打高性价比的内存优化型入门选择。其核心特点是8G大内存适配轻量内存密集场景,计费模式灵活可控,既能满足个人开发者的复杂测试项目需求,也能支撑小微企业的基础业务运行,无需为闲置资源过度付费。以下从优惠活动价格、性能表现、适用场景及避坑要点四方面,用通俗语言详细解析。
224 153
|
4天前
|
机器学习/深度学习 人工智能 算法
炎鹊「Nexus Agent V1.0」:垂直领域AI应用的原生能力引擎
炎鹊AI「Nexus Agent V1.0」是垂直行业专属AI原生引擎,融合大模型、AIGA决策大脑、行业知识图谱与专属模型,打造“感知-决策-执行”闭环。支持21个行业低代码构建工具型、员工型、决策型AI应用,实现技术到业务价值的高效转化,推动AI从实验走向规模化落地。(239字)
243 1

热门文章

最新文章