字符函数和字符串函数

这篇文章和大家分享一下字符函数和字符串函数。

1. 字符分类函数

在C语言中有一系列函数专门做字符分类的,也就是一个字符是属于什么类型的字符,这些字符都需要一个头文件 ctype.h。

函数它的参数符合下列条件就返回真
iscntrl任何控制符
isspace空白字符:空格' ',换页'\f',换行'\n',回车'\r',制表符'\t'或者垂直制表符'\v'
isdigit十进制0-9
isxdigit十六进制数字,包括所有十进制数字,小写字母a-f,大写字母A-F
islower小写字母a-f
isupper大写字母A-F
islpha字母a-z或A-Z
isalnum字母或者数字,0-9,a-z,A-Z
ispunct标点符号,任何属于数字或者字母的图形字符
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

这些函数的使用方法非常相似,这里我们以其中一个函数的讲解为例:

int islower(int c);

islower是可以判断参数部分c是否是小写字母。我们可以通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,就返回0。

上实战:写一个代码将字符串中的小写字母换成大写字母,其他的不变。

#include<stdio.h>
#include<ctype.h>
int main()
{
  int i=0;
  char arr[]="Asdfghjkl";
  char c;
  while(arr[i])
   {
     c=arr[i];
     if(islower(c))
       c-=32;
     putchar(c);
     i++;
   }
  return 0;
}

2. 字符转换函数 

c语言提供了两个字符转换函数分别是:

int tolower(int c);//将参数里面的大写字母转换成小写字母
int toupper(int c);//将参数里面的小写字母转换成大写字母

 上面的代码,我们将小写转换成大写,是-32完成的效果,有了转换函数,我们就可以使用toupper来实现这种效果。

#include<stdio.h>
#include<ctype.h>
int main()
{
  int i=0;
  char arr[]="asdfghjkl";
  char c;
  while(arr[i])
   {
     c=arr[i];
     if(islower(c))
       c=toupper(c);
     putchar(c);
     i++;
   }
  return 0;
}

3. strlen的使用和模拟实现 

size_t strlen(const char * str);

 字符串以'\0'作为结尾标识,strlen函数返回的是字符串中'\0'之前出现的字符个数(不包含\0),参数指向的字符串必须要以’\0‘作为结尾标识,注意函数的返回值是size_t,是无符号的,下面是strlen的模拟实现(仿照strlen函数的参数,返回类型,功能写一个相似的函数):

方式1:

//计算器方式
int my_strlen(const char* str)
{
  int count=0;
  assert(str);
  while(*str)
  {
    count++;
    str++;
  }
  return count; 
}

方式2:

//不创建临时变量计算器
int my_strlen(const *char)
{
  assert(*str);
  if(*str==''\0)
    return 0;
  else
    return 1+my_strlen(str+1);
}

方法3:

//指针-指针形式
int my_strlen
{
  assert(str);
  char *p=s;
  while(*p!='\0')
   p++;
  return p-s;
}

4. strcpy函数的使用和模拟实现

char *strcpy(char *destination,const char *source);

我们看一下C++官网对strcpy的介绍:

strcpy函数的功能:拷贝字符串。

注意事项:1. 源字符串中必须包含'\0',同时'\0'也会被拷贝到目标空间。

                  2.必须要保证目标空间足够大,能放得下拷贝来的数据。

                  3.保证目标空间可修改

模拟实现strcpy函数:

#include<stdio.h>
void my_strcpy(char *dest,char *src)
{
  while(*src!='\0')
   {
     *dest=*src;
     dest++;
     src++;
   }
  *dest=*src;
}
int main()
{
  char arr1[]="qwertyuiop";
  char arr2[20]={0};
  my_strcpy(arr2,arr1);
  printf("%s\n",arr2);
  return 0;
}

 5. strcat函数的使用和模拟实现

char *strcat (char *destination,const char *source);

我们看一下C++官网对strcat函数的介绍:

由于C++官网是英文环境,将页面翻译成中文,strcat被翻译成了斯特卡特。

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[20]="hello";
  char arr2[30]="world";
  strcat(arr1,arr2);
  printf("%s\n",arr1); 
  return 0;
}

 strcat函数的功能:字符串追加。 

注意事项:1. 目标空间中要有\0(从哪里开始追加),源字符串中也要有\0(追加到哪里结束)。

                  2.目标空间足够大,目标可以修改。

模拟实现strcat函数:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest,const char* src)
{
  char* ret=dest;
  assert(dest&&src);
  //找到目标空间中的\0
  while(*dest!='\0')
  {
    dest++; 
  } 
  //拷贝数据
  while(*dest++=*src++)
  {
    ;//这是空语句
  }
  return ret;
}
int main()
{
  char arr1[30]="hello";
  char arr2[30]="world";
  printf("%s\n",my_strcat(arr1,arr2));
  return 0;
}

6.strcmp函数的使用和模拟实现

int strcmp(const char* str1,const char* str2);

我们看一下C++官网对strcmp函数的介绍:

#include<stdio.h>
#include<string.h>
int main()
{
  int ret=strcmp("asd","asdf");//比较两个字符串
  printf("%d\n",ret);
  return 0;
}

 

strcmp函数的功能:比较两个字符串

strcmp函数规定标准:1.第⼀个字符串大于第⼆个字符串,则返回大于0的数字

                                    2. 第⼀个字符串等于第⼆个字符串,则返回0

                                    3.第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

strcmp函数是怎么判断两个字符串的,它比较的是两个字符串中对应位置上的ASC||码值的大小。

模拟实现strcmp函数:

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* s1,const char* s2)
{
  assert(s1!=NULL);
  assert(s2!=NULL);
  while(*s1==*s2)
   {
     if(s1=='\0')
       return 0;
     s1++;
     s2++;
   }
  return *s1-*s2;
}
int main()
{
  int ret=my_strcmp("asdf","asd");
  printf("%d\n",ret);
  return  0;
}

7.strncpy函数的使用

char* strcmpy(char* destination,const char* source,size_t num);

我们来看一下C++官网对strncpy的介绍: 

通过对strncpy函数的介绍,我们可以发现它和strcpy函数的功能相似,而且写法还很相似,strncpy函数需要三个参数,而strcpy函数是两个参数,size_t num 表示的是拷贝字符串时拷贝字符串的个数(下面的strncat函数和strncmp函数中的size_t num和这里的意义相同),下面我们通过代码及其运行结果来更深入的了解strncpy函数:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[30]="xxxxxxxxxx";
  char arr2[]="abcdef";
  strncpy(arr1,arr2,3);
  printf("%s\n",arr1);
  return 0;
}

 那如果size_t num比arr2[]中存放的字符串的字符个数还要多会怎么样呢?多出来的部分会存放\0,那么我们一起通过下面的代码及其监视来了解吧:

#include<stdio.h>
#include<string.h>
int main()
{
  char* arr1[30]="xxxxxxxxxx";
  char* arr2[]="ab";
  strncpy(arr1,arr2,5);
  printf("%s\n",arr1);
  return 0; 
}

8. strncat函数的使用 

 

char* strncat(char* destination,const char* source,size_t num);

我们看一下C++官网对strncat函数的介绍:

这里strncat函数被翻译成了斯特恩卡特(C++官网是英文环境,为了方便大家看懂进行了页面翻译),下面我们看一段代码及其运行结果来更深入的了解strncat函数:

 

#include<stdio.h>
#include<string.h>
int main()
{
  char* arr1[30]="abc\0xxxxxxxx";//放\0的原因:追加时是在\0的位置开始追加字符
  char* arr2[]="defghij";
  strncat(arr1,arr2,5);
  printf("%s\n",arr1);
  return 0;
}

那如果size_t num 比arr2[]中存放的字符串个数还要多会怎么样呢?只会将arr2[]中的所有字符都追加(包括\0),我们看一下这段代码及其监视结果来了解这个知识点:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[30]="adc\0xxxxxxx";
  char arr2[]="de";
  strncat(arr1,arr2,5);
  printf("%s\n",arr1);
  return 0;
}

9.strncmp函数的使用 

int strncmp(const char* str1,const char* str2,size_t num);

我们看一下C++官网对strncpm函数的介绍:

这里size_t num的含义是:比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不⼀ 样,就提前结束,⼤的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0,我们再看一下C++官网对strncmp函数返回值的描述:

我们通过下面这段代码来了解strncmp函数的知识点:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[30]="abcdefg";
  char arr2[]="abcqwer";
  int ret=strncmp(arr1,arr2,3);
  printf("%d\n",ret);
  return 0;
}

 

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[30]="abcdefg";
  char arr2[]="abcqwer";
  int ret=strncmp(arr1,arr2,4);
  printf("%d\n",ret);
  return 0;
}

 

 

10.strstr函数的使用和模拟实现 

char* strstr(const char* str1,const char* str2);

 我们看一下C++官网对strstr函数的介绍:

strstr函数的功能是:在一个字符串中找一个子字符串,返回str2在str1中第一次出现的位置,如果str2在str1中没有出现,就返回NULL。

我们通过下面这段代码来深入的理解这里的知识点:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[]="abcdefabcdef";
  char arr2[]="def";
  char* ret=strstr(arr1,arr2);//arr1中出现了两次'def',返回的是第一次出现的位置('d'的位置)
  printf("%s\n",ret);
  return 0;
}

 

那么下面我们来模拟实现strstr函数:

#include<stdio.h>
#include<assert.h>
const char* my_strstr(const char* str1,const char* str2)
{
  assert(str1);
  assert(str2);
  //cp记录可能找到匹配的字符串的起始位置
  //s1遍历cp后面的字符串内容然后与s2(从str2首元素开始遍历的内容)进行比较
  const char* cp=str1;
  const char* s1=NULL;
  const char* s2=NULL;
  //如果字字符串是空字符串,直接返回str1
  if(*str2=='\0')
     return str1;
  while(*cp)
    {
      s1=cp;
      s2=str2;
      //判断s1和s2是否相等,不相等的话直接跳出循环
      while(*s1==*s2&&*s1&&*s2)
        {
          s1++;
          s2++;
        }
      //判断s2是否等于\0,等于的话表示子字符串已经遍历结束,然后返回此时cp的位置
      if(*s2=='\0')
        return cp;
   cp++;
     }
  return NULL;
}
int main()
{
  char arr1[]="abbbcdef";
  char arr2[]="bbc";
  const char* ret=my_strstr(arr1,arr2);
  if(ret!=NULL)
    printf("%s\n",ret);
  else
    printf("找不到"); 
  return 0;
}

 

这种方式是一种暴力求解方式,还有一种更好的方式:KMP算法,它的效率高,但是难度大,难以理解,这里就不和大家分享KMP算法了,感兴趣的可以去搜索一下。

11.strtok函数的使用 

char* strtok(char* str,const char* delimiters);

 我们看一下C++官网对strtok函数的介绍:

strtok函数和strcat函数一样页面翻译被翻译成了中文(斯特托克就是strtok函数),delimiters参数指向一个字符串,定义了⽤作分隔符的字符集合,第⼀个参数指定⼀个字符串,它包含了0个或者多个由delimiters字符串中⼀个或者多个分隔符分割的标记。strtok函数找到str中的下⼀个标记,并将其用\0 结尾,返回⼀个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。)strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。如果字符串中不存在更多的标记,则返回 NULL 指针。那么我们通过下面这段代码来了解这些知识点吧:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr[]="3224349147@qq.com";//这里就以我的QQ邮箱为例子,这里的'@'和'.'就是分割符
  const char* p="@.";
  char* r=NULL;
  for(r=strtok(arr,p);r!=NULL;r=strtok(NULL,p))
   {
     printf("%s\n",r);
   }
  return 0;
}

本篇博客就分享到这里了,大家有问题可以评论出来。 

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野生的编程萌新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值