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

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

一、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语言中的库函数有关字符函数和字符串函数有更深层的理解.

目录
相关文章
|
3天前
|
存储 人工智能 安全
AI 越智能,数据越危险?
阿里云提供AI全栈安全能力,为客户构建全链路数据保护体系,让企业敢用、能用、放心用
|
6天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
402 93
|
6天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
399 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
6天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
291 158
|
14天前
|
机器人 API 调度
基于 DMS Dify+Notebook+Airflow 实现 Agent 的一站式开发
本文提出“DMS Dify + Notebook + Airflow”三位一体架构,解决 Dify 在代码执行与定时调度上的局限。通过 Notebook 扩展 Python 环境,Airflow实现任务调度,构建可扩展、可运维的企业级智能 Agent 系统,提升大模型应用的工程化能力。