C语言——字符串函数

一.求字符串长度

strlen

  • ‘\0’作为结束标志,strlen函数返回的是在字符串中’\0’之前的字符个数(不包括’\0’)
  • strlen函数的返回值是无符号
  • 参数指向的字符串必须要以’\0’结束
  • 头文件为 string.h
#include<stdio.h>
#include<string.h>
int main()
{
  char arr[] = “abc”;//a  b  c  \0
  char arr2[] = {'a','b','c'};
  int len = strlen(arr);
  int len2 = strlen(arr2);
  printf("%d\n",len);//3
  printf("%d\n",len2);//随机值
  return 0;
}

对于库函数strlen
在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main()
{
  if(strlen("abc") - strlen("abcdef") > 0)//是一个大的正整数
  {
    printf(">\n");
  }
  else
  {
    printf("<\n");
  }
  return 0;
}//>      .并不是<

而对于自己弄得strlen函数,并不会有无负数这样的情况

#include<stdio.h>
int my_strlen(const char* str)
{
  int  count = 0;//计数器
  assert(str != NULL);
  while(*str != '\0')
  {
    count++;
    str++;
  }
  return count;
}
int main()
{
  if(strlen("abc") - strlen("abcdef") > 0)//3-6 = -3<0
  {
    printf(">\n");
  }
  else
  {
    printf("<\n");
  }
  return 0;

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

strcpy(字符串拷贝)函数

  • 源字符串 必须 包括’\0’,进行结束。
  • 拷贝时将前面的内容拷贝过去的同时,也会将’\0’拷贝了过去
  • 目标空间必须足够大,确保能存放源字符串
  • 目标空间必须可变,不能用const来修饰。
  • 头文件为 string.h
#include<stdio.h>
#include<string.h>
int main()
{
  char arr[20] = { 0 };
  //char* p = "qwewe";//是字符串首字符的地址
  strcpy(arr,"qwewe");//字符串拷贝
  printf("%s\n",arr);
  return 0;
}
//qwewe

举例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr[20] = "#########";
  strcpy(arr,"hgyvg");
  printf("%s\n",arr);
  return 0;
}

发现’\0’也被拷过去了,所以单纯的字符是不行的,后面无’\0’,不知道什么时候截止,如:

char arr[20] = "########";
char arr2[] = {'a','b','c'};
strcpy(arr,arr2);

strcat(字符串追加)函数

  • 源字符串 必须 包括’\0’,进行结束。
  • 目标空间必须可变
  • 目标空间必须足够大,确保能追加进源字符串
  • 返回的是目标空间的起始地址
  • ​头文件为 string.h
#include <stdio.h>
#include <string.h>
int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world";
    strcat(arr1, arr2);
    printf("%s\n", arr1);
    return 0;
}
//hello world
模拟实现strcat函数
#include <stdio.h>
char* my_strcat(char* dest,const char* arc)
{
   char* ret = dest;
   //先找到arr1的\0
   while(*dest)
   {
      dest++;
   }
   //追加源字符串,包含0
   while(*dest++ = *arc++)
   {
     ;
   }
    return ret;
}
int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world";
    my_strcat(arr1, arr2);
    printf("%s\n", arr1);
    return 0;
}
//hello world

?

那么字符串能自己追加自己吗?————答案是不能

自己追加自己,会将’\0’覆盖到底,一旦没有结束标志则会出错

strcmp(字符串比较)函数

  • ​头文件为 string.h

当你想比较两个字符串时

#include<stdio.h>
int main()
{
  //错误示例1:
    char* p = "qwe";//给p的是p的地址
    char* q = "zxcvb";//给q的是q的地址
    if(p>q)
    {
      printf(">\n");
    }
    else
    {
      printf("<\n");
    }
  //错误示例2:
    if("qwe" > "zxcvb")
    {
       ;
    }
  //1,2都是在比较地址,而不是字符串
  //正确:
    用strcmp从前往后比较相应位置的ASCLL值
    char* p = "qwe";//给p的是p的地址
    char* q = "zxcvb";//给q的是q的地址 
    int ret = strcmp(p,q);
    if(ret > 0)
    {
      printf("p > q\n");
    }
    else if(ret < 0)
    {
      printf("p < q\n");
    }
    else
    {
      printf("p = q\n");
    }
  return 0;
}

用strcmp函数从前往后比较相应位置的ASCLL值,直到第一个str1大于 或 小于str2时,判断为 > 或 < .都一样时为 =

例子:

int ret = strcmp("axsc","axdc");
printf("%d\n",ret);
//结果:1
int ret = strcmp("axaec","axdc");
printf("%d\n",ret);
//结果:-1
int ret = strcmp("axdc","axdc");
printf("%d\n",ret);
//结果:0
模拟实现strcmp函数:

```c
#include<stdio.h>
int my_strcmp(const char* str1,const char* str2)//不用改变时加上const更健壮
{
  while(*str1 == *str2)
  {
    if(*str1 == '\0')
    {
      return 0;
    }
     str1++;
     str2++;
  }
  if(*str1 > *str2)
  {
     return 1;
  }
  else
  {
     return -1;
  }
}
int main()
{
    char* p = "qwe";
    char* q = "zxcvb";
    int ret = my_strcmp(p,q);
    if(ret > 0)
    {
      printf("p > q\n");
    }
    else if(ret < 0)
    {
      printf("p < q\n");
    }
    else
    {
      printf("p = q\n");
    }
  return 0;
}

三.长度受限制的字符串函数

strncpy

  • 由于strcpy不考虑目标空间的大小,可能会不安全进行报错,进而有strncpy,相对安全
  • 当拷贝数 大于原空间大小时,用0补充
  • ​头文件为 string.h
#include<stdio.h>
#include<string.h>
int main()
{
   char a1[] = "abcdefzxcc";
   char a2[] = "qwer";
   strncpy(a1,a2,5);
   printf("%s\n",a1);
   return 0;
}

strncat

  • 追加x个字符给目标字符串
  • 当x大于源字符串个数时,追加完源字符串即可,不用补,因为’\0’也拷过去了
  • 当x小于源字符串个数时,会自动加一个’\0’。x是几就拷贝几个
  • ​头文件为 string.h
#include <stdio.h>
#include <string.h>
int main()
{
    char a1[] = "hello";
    char a2[] = "world";
    strncat(a1, a2, 3); 
    printf("%s\n", a1);
    return 0;
}
//结果:hello wor

strncmp

  • 进行前x个字符从前往后相应位置的比较
  • ​头文件为 string.h
#include <stdio.h>
#include <string.h>
int main()
{
    const char* p = "abcdef";
    const char* q = "abdsfsdfr";
    int ret = strncmp(p, q, 4);//前4个字符的比较
    printf("%d\n", ret);
    return 0;
}
//-1

四.字符串查找

strstr(字符串查找)函数

  • 返回字符串中首次出现子串的地址。若 str2 是 str1 的子串,则返回 str2 在 str1 中 首次 出现的 地址。如果 str2 不是 str1 的子串,则返回 null 。
  • 头文件为 string.h
#include <stdio.h>
#include <string.h>
int main()
{
    char a1[] = "abcde";
    char a2[] = "dnf";
    char* ret = strstr(a1, a2);
    printf("%s\n", ret);
    return 0;
}
//null
#include <stdio.h>
   #include <string.h> int main() {
       char a1[] = "abcde";
       char a2[] = "cde";
       char* ret = strstr(a1, a2);
       printf("%s\n", ret);
       return 0; } //cde
模拟实现strstr函数
#include <stdio.h>
#include<assert.h>
char* my_strstr(const char* str1,const char* str2)
{
  assert(str1 && str2);
  const char* s1 = NULL;
  const char* s2 = NULL;
  const char* cp = str1;
  if(*str2 == '\0')
  {
    return (char*)str1;
  }
  
  while(*cp)
  {
    s1 = cp;
    s2 = str2;
    while(*s1 && *s2 && (*s1 == *s2))
    {
     s1++;
     s2++;
    }
    if(*s2 == '\0')
    {
       return (char*)cp;
    }
    cp++;
  }
  return NULL;     
}
int main()
{
    char a1[] = "abcde";
    char a2[] = "dnf";
    char* ret = my_strstr(a1, a2);
    if(ret == NULL)
    {
      printf("没找到\n");
    }
    else
    {
      printf("找到了: %s\n",ret);
    }
    printf("%s\n", ret);
    return 0;
}

strtok(切割字符串)函数

  • delimiters参数是个字符参数,定义了用作分隔符的字符集合

  • strtok函数找到str的下一个标记,用\0结尾,返回一个指向这个标记的指针(注:strtok函数会改变被操作的字符串,所以会用一个临时的量去拷贝内容,其可修改)

  • 第一个参数不为NULL时,会保存​字符串的第一个标记的位置;再次调用函数时,第一个参数为NULL,从被保存的位置开始查找下一个标记

#include<stdio.h>
int main()
{
  char arr[] = "zyx@bitedu.tech";
  char tmp[20] = { 0 }; 
  strcpy(tmp,arr);
  char* ret = NULL;
  ret = strtok(tmp,"@.");
  printf("%s\n",ret);
  ret = strtok(NULL,"@.");
  printf("%s\n",ret);
  ret = strtok(NULL,"@.");
  printf("%s\n",ret);
  return 0;
}

strerror

  • 在使用库函数的时候;调用失败会设置错误码
  • strerror会将错误码转化为所对应的错误信息
#include<stdio.h>
#include<string.h>
int main()
{
  printf("%s\n",strerror(0));
  printf("%s\n",strerror(1));
  printf("%s\n",strerror(2)); 
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值