目录:
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;
}
如果有什么问题大家可以提出来,我们共同修改,共同进步。