字符相关函数和字符串函数

目录:

1. 字符分类函数

2.字符转换函数

3.strlen的使用和模拟实现

4.strcpy的使用和模拟实现

5.strcat的使用和模拟实现

6.strcmp的使用和模拟实现

7.strncpy的使用和模拟实现

8.strncat的使用和模拟实现

9.strncmp的使用和模拟实现

10.strstr的使用和模拟实现

11.strtok的使用和模拟实现

12.strerror的使用和模拟实现


1.字符分类函数

c语言中有一些函数是专门做字符分类的,也就是一个字符是属于什么

类型的字符。使用这些函数之前需要包含一个头文件

“控制字符”是指那些具有某种特殊功能、不会显示在屏幕上、不会占用字符位置的特殊字符。无法在屏幕上打印的字符称为控制字符。例如,退格键,转义符,换行符等。

接下来我们介绍一下islower函数的使用

#include<stdio.h>
#include<ctype.h>
int main()
{
    //islower是用来判断参数是否是小写字母
    //如果是小写字母返回非0
    //如果不是返回0
    int ret=islower('a');
    printf("%d\n",ret);
    return 0;
}

以上函数均类似于islower

将字符串中的小写字母转换为大写字母

#include<stdio.h>
include<string.h>
int  main()
{
    //'a' 97
    //'B' 65
    char str[]="i im a student";
    size_t len=strlen(str);
    int i=0;
    for(i=0;i<len;i++)
    {
        if(islower(str[i]))
         //str[i]=str[i]-32; 
         str[i]=toupper(str[i]);   
    }
    printf("%s\n",str);
    return 0;
}

2.字符转换函数

c语言提供了2个字符转换函数(也需要包含头文件):

int tolower(int c)//将参数传进去的大写字母转为小写字母

int toupper(int c)//将参数传进去的小写字母转为大写字母

这里将字符的ascll码值传给形参,返回转换后的ascll码值

#include<stdio.h>
#include<ctype.h>
int main()
{
    char ch=0;
    scanf("%c",&ch);
    //ch=ch-32;
    ch=toupper(ch);
    ptintf("%c\n",ch);
    return 0;
}

3.strlen的使用和模拟实现

#include<stdio.h>
#include<string.h>
int main()
{
    //需要包含头文件<string.h>
    //strlen-是求字符串的长度的
    //字符串的结束标志是\0
    //strlen统计的是\0之前出现的字符的个数
    char arr[]="abcdef";
    size_t len=strlen(arr);
    printf("%d\n",len);
    
    
    
    //1. strlen函数是要正确获得字符串长度的话,必须要求字符串中含有\0
    //2. 要注意strlen的返回值是size_t(无符号整形)
    char arr[]={'a','b','c'};
    size_t len=strlen(arr);
    printf("%zd\n",len);
    
    
    if(strlen("abc")-strlen("abcdef")>0)
    printf(">\n");
    else
    printf("<=\n");
    //这里打印的是> 因为上述的结果虽然是-3,但是因为是两个无符号整形的数在相减,所以
    //最后得到的结果也应该是无符号整形的数据 即>0的数据
    return 0;
}
//strlen的模拟实现
//仿照strlen函数的参数,返回类型,功能写一个类似的函数
#include<stdio.h>
#include<assert.h>
size_t my_strlen1(const char * str)
{
    size_t count=0;
    assert(str!=NULL);
    while(*str!='\0')
    {
        count++;
        str++;    
    }
    return count;
}
//指针-指针-->地址-地址
//得到的是指针和指针之间元素的个数
size_t my_strlen2(const char*str)
{
    const char*start=str;
    while(*str!='\0')
    {
        str++;    
    }
    return str-start;
}
//递归的方式
//模拟实现strlen函数,不能使用临时变量
size_t my_strlen3(const char*str)
{
       if(*str!='\0')
       return 1+my_strlen3(str+1);
       //这里尽量不要修改str的值
       else
       return 0;
}
int main()
{
    char str[]="abcdef";
    size_t len=my_strlen1(str);
    printf("%zd",len);
    return 0;
    
}

4.strcpy的使用和模拟实现

#include<stdio.h>
#include<string.h>
int main()
{
    //strcpy
    //函数的功能:拷贝字符串
    //注意事项:
    //1.源字符串中必须含有'\0',同时\0也会被拷贝到目标空间    
    //2.程序员自己要保证目标空间要足够大,能放得下拷贝来的数据
    //3.保证目标空间必须可以修改
    
    char arr1[]="hello abc";
    char arr2[20]="xxxxxxxxxx";
    //char arr2[4]="xxx";
    strcpy(arr2,arr1);
    printf("%s\n",arr2);
    char arr1[4]="abc";
    char *p="ahhfiahfjah";//字符串常量不可以被修改
    strcpy(p,arr1);
    printf("%s\n",p);
    return 0;
}

strcpy的模拟实现

#include<stdio.h>
void my_strcpy1(char *dest,char *src)
{
    while(*src!='\0')
    {
        *dest=*src;
        dest++;
        src++;            
    }
    *dest=*src;
}
void my_strcpy2(char *dest,char *src)
{
    while(*dest++ = *src++)
    {              
    }
    *dest=*src;
}
void my_strcpy3(char *dest,char *src)
{
    assert(dest&&src);
    while(*dest++ = *src++)
    {              
    }
}
//dest指向的空间是需要改变的,但是src指向的空间是不期望被改变的
void my_strcpy4(char *dest,const char *src)
{
     assert(dest&&src);
    while(*dest++ = *src++)
    {              
    }
 }
 char* my_strcpy5(char *dest,char *src)
{
    char * ret=dest;
     assert(dest&&src);
    while(*dest++ = *src++)
    {              
    }
    return ret;
 } 
int main()
{
    char arr1[]="abcdef";
    char arr2[20]={0};
    my_strcpy(arr2,arr1);
    printf("%s\n",arr2);
    //my_strcpy5
    //链式访问
    //printf("%s\n",my_strcpy(arr2,arr1));
    return 0;
}

5.strcat的使用和模拟实现

strcat---字符串追加

1.目标空间中得有\0(从哪里追加),源字符串中得有\0(追加到什么时候结束)

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

#include<string.h>
int main()
{
    char arr1[20]="hello ";
    char *p="world";
    //strcat(arr1,"world");
    strcat(arr1,p);
    return 0;
}

strcat的模拟实现

#include<stdio.h>
char* my_strcat(char *dest,const char *src)
{
    char *ret=dest;
    assert(dest&&src);
    while(*dest!='\0')
    {
        dest++;    
    }
    while(*dest++=*src++)
    {
        ;    
    }
    return ret;
    
}
int main()
{
    char arr1[20]="hello ";
    char *p="world";
    //strcat(arr1,"world");
    printf("%s\n",my_strcat(arr1,p));
    return 0;
}

6.strcmp的使用和模拟实现

strcmp--string compare 字符串比较

用来比较2个字符串的大小关系

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

比较两个字符串中对应位置上字符按照字典序比较

返回值:前字符串>后字符串 返回>0的数

前字符串==后字符串 返回0的数

前字符串<后字符串 返回<0的数

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

strcmp模拟实现

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char*arr1,const char* arr2)
{
    assert(arr1!=NULL);
    assert(arr2!=NULL);
    while(*arr1==*arr2)
    {
        if(*arr1=='\0')
        {
            return 0;        
        }
        arr1++;
        arr2++;    
    }
    //if(*arr1>*arr2)
    //return 1;
    //else
    //return -1;
    return arr1-arr2;
}
int main()
{
    int ret=my_strcmp("abcdef","abc");
    if(ret>0)
    {
        printf(">");    
    }else if(ret==0)
    {
        printf("==");    
    }
    else
    printf("<");
    return 0;
}

strcpy strcat strcmp 都是长度不受限制的字符串函数

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[3]={0};
    char arr2[]="abcdef";
    strcpy(arr1,arr2);
    printf("%s\n",arr1);
    //即使这里的arr1会被打印,但是程序会崩掉
    return 0;
}

strncpy strncat strncmp是长度受限制的字符串函数

它们的函数声明为:

char * strncpy(const char *destination,const char *source,size_t)

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

char * strncmp(const char *arr1,const char *arr2,size_t)

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[10]="xxxxxxxxxx";
   // char arr2[]="abcdef";
    char arr2[]="ab";
    strncpy(arr1,arr2,5);
    printf("%s\n",arr1);
    //这里要拷贝5个字符的话,前两个正常拷贝,剩余的三个用\0拷贝进去
    return 0;
}

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20]="abc\0xxxxxxxxxx";
    char arr2[]="def";
    strncat(arr1,arr2,5);
    printf("%s\n",arr1);
    //这里拷贝3个字符后,然后仅仅将一个\0拷贝到arr1中
    return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[20]="abcdef";
    char arr2[]="abcqwer";
    int ret=strncmp(arr1,arr2,4);
    printf("%d\n",ret);
    return 0;
}

7.strstr 的使用和模拟实现

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

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

strstr函数的功能:如果str2在str1中 返回str2在str1中第一次出现的位置

如果str2没有在str1中出现就返回NULL指针

#include<stdio.h>
#include<string.h>
int main()
{
    char arr1[]="abcdefabcdef";
    char arr2[]="def";
    char *ret=strstr(arr1,arr2);
    if(ret!=NULL)
    printf("%s\n",ret);
    else
    printf("找不到\n");
    
    return 0;
}
const char *my_strstr(const char*arr1,const char*arr2)
{
    assert(str1&&str2);
    const char *cp=arr1;
    const char *s1=NULL;
    const char *s2=NULL;
    //如果子串是空字符串,直接返回str1
    if(*str2=='\0')
    return str1;
    while(*cp)
    {
        s1=cp;
        s2=str2;
        while(*s1==*s2&&*s1&&*s2)
        {
            s1++;
            s2++;        
        }
        if(*s2=='\0')
        return cp;    
    }
    return NULL;
}
int main()
{
    char arr1[]="abcdefabcdef";
    char arr2[]="def";
    char *ret=my_strstr(arr1,arr2);
    if(ret!=NULL)
    printf("%s\n",ret);
    else
    printf("找不到\n");
    
    return 0;
}

8.strtok函数的使用

char *strtok(char*str,char*sep)

sep参数指向一个字符串,用来定义用作分隔符的字符集合

第一个参数指定一个字符串,它包含0个或者多个由sep字符串中一个或者多个分割符分割的标记

strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改)

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

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

如果字符串中不存在更多的标记,则返回NULL

#include<stdio.h>
#include<string.h>
int main()
{
    char arr[]="zpengwei@yeah.net.xxxx@jjjjj.ssss";//@ .分割符
    char buf[30]={0};
    strcpy(buf,arr);
    char *p="@.";
   /* char *s=strtok(buf,p);
    printf("%s\n",s);
    s=strtok(NULL,p);
    printf("%s\n",s);
    s=strtok(NULL,p);
    printf("%s\n",s);
*/
    char *r=NULL;
    for(r=strtok(buf,p);r!=NULL;r=strtok(NULL,p))
    {
        printf("%s\n",r);    
    }
    return 0;
}

9.strerror的使用

其函数的声明:

char *strerror(int errnum);

其返回一个错误码所对应的错误信息字符串的起始地址

#include<stdio.h>
#include<string.h>
int main()
{
    int i=0;
    for(i=0;i<10;i++)
    {
        char * ret=strerror(i);
        printf("%d:%s\n",%d,ret);    
    }
    return 0;
}

在c语言中的库函数中设计一些错误码,当我们库函数在调用的过程中发生了各种错误,要记录下来,这时候记录的就是错误码 例如:404

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

errno是一个c语言的全局变量

打开文件--读写文件之前,需要打开文件

读写文件前,需要打开文件,如果要打开成功,需要文件是存在的,如果文件不存在,则打开失败,fopen会返回NULL

#include<string.h>
#include<errno.h>
int main()
{
    FILE *pf=fopen("add.txt","r");
    if(pf==NULL)
    {
        printf("打开文件失败,失败的原因:%s\n",strerror(errno));    
        return 1;    
    }
    else
    {
        printf("打开文件失败\n");    
    }
    
    return 0;
}

相关的函数:perror 头文件是:

void perror(const char *str)//打印错误信息

#include<string.h>
#include<errno.h>
#include<stdio.h>
int main()
{
    FILE *pf=fopen("add.txt","r");
    if(pf==NULL)
    {
       // printf("打开文件失败,失败的原因:%s\n",strerror(errno));    
        perror("fopen");
        //相当于printf("fopen: %s\n",strerror(errno));
        return 1;    
    }
    else
    {
        printf("打开文件失败\n");    
    }
    
    return 0;
}

如果有什么问题大家可以提出来,我们共同修改,共同进步。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值