首先介绍一下字符串操作函数大概都有哪些:
求字符串长度
strlen
长度不受限制的字符串函数
strcpy
strcat
strcmp
长度受限制的字符串函数介绍(对要操作的字节数给出了限制)
strncpy
strncat
strncmp
字符串查找
strstr
strtok
错误信息报告
strerror
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者 字符数组中。
字符串常量适用于那些对它不做修改的字符串函数.要认真看噢,进入正题
计算字符串长度
//格式
size_t strlen (const char* str)
从地址位开始往后找直到’\0’处停止(所以我们在使用时,目标字符串内最好得有’\0’,否则得到的就是随机值),且’\0’不会计数
注意:
1.参数类型要用const修饰,加个const防止从strlen函数内部修改目标字符串内容(下面也同理)
2.strlen函数的返回值是size_t类型的无符号整型数,所以当直接使用其返回值进行计算时,由于内存对无符号类型数的读与取规则,可能会出错
拷贝字符串
//格式
char* strcpy(char* dest,const char* src)
注意:
1.由于拷贝函数是以源字符串的’\0’来截止拷贝操作的,所以要确保源字符串中有’\0’,否则将会传入很多随机值甚至报错(’\0’也是会被存进目标字符串中去的)
2.目标字符串空间必须足够大(拷贝时是不会考虑空间是否够大的)
3.目标必须可变(因为是将拷贝内容放进去,所以肯定得为可修改的)
4.这里将返回类型设置为了char * 而不是void ,使其有了函数的链式访问属性,可直接将返回值作为其他函数的参数进行使用(下面同理)
ex:
printf("%s\n",strcpy(s1,s2));
追加字符串
将源字符串接到字符串后面
//格式
char* strcat(char* dest,const char* src)
注意:
1.源字符串中也要有’\0’,否则传进去随机值且可能会导致越界报错
2.源字符串接到目标字符串后面时会从‘\0’处开始接
比较字符串函数
从第一位开始比较同位置的字符ascii码值大小;如果前者大于后者则返回大于0的整型值,后者大于前者返回小于0的整型值,两者相等返回0
//格式
int strcmp(const char* dest,const char* drc)
区别就是多传入个限制访问的字节数的参数而已,但还是有一些注意事项,下面分别简单说明一下
//格式
char* strncpy(char* dest,const char* src,size_t num)
注意:
当源字符串小于需要传入的字节个数时,会自动将’\0’补位拷贝进去
//格式
char* strncat(char* dest,char* src,size_t num)
注意:
1.当需传入的字节数<源字符串大小时,会主动在目标字符串后一位补上’\0’
2.反之,则会在追加完字符串后再追加个’\0’然后停止追加
总之,就是都会增加个’\0’使该操作比较安全
就是限制比较的字符个数
int strncmp(const char* dest,const char* rc,size_t num)
查找子字符串函数
在目标字符串中寻找是否有源字符串,找到的话返回目标字符串中开始相等的地址,否则返回NULL指针
//格式
char* strstr(const char* dest,const char* src)
注意:
1.需查找的字符串内容不能为空,无法在字符串中寻找空值
字符串分隔函数
char*strtok(char* dest,const char* sep)
第二个参数是一个自己定义的分隔符的字符串集合(只有写在sep里面的才会被当作是分隔符分开),返回值为返回标记的指针(标记就是被分隔开的子字符串)
注意:
1.当返回第一个标记时(即此子字符串在目标字符串中是一号位置),第一个参数必须为有效地址;且此函数内部会将第一个地址参数保存(可能用了static函数转换成静态变量进行储存)
2.当需要返回的不是第一个标记时,第一个参数为NULL(此时函数会在上次保存的地址中从同一个字符串中开始寻找下一个标记)
3.strtok找到一个标记后会将其用’\0’结尾,并返回其地址
4.strtok函数对字符串分隔操作会改变字符串内容,所以我们通常都是拷贝一份临时变量防止目标字符串被改变。
将错误码翻译成错误信息
//格式
char* strerror(int errnum)
传入的参数为错误码,返回值为错误信息的字符串常量首元素地址((char*)因为错误信息是作为字符串常量保存在c语言中可以直接用其指针打印出来的)
这个函数相信大家一听多少有点懵b,错误码是什么?又该怎么调用传参呢?接下来就给大家简单讲一些知识
当库函数使用的时候,发生错误会把errno这个全局的错误变量设置为本次执行库函数产生的错误码,errno是c语言提供的一个全局变量,可以直接使用,放在
文件中的
所以在调用库函数发生错误时可以使用strerror函数来查询错误原因(把errno直接传参就行了,但要记得声明头文件)
函数 | 如果他的参数符合下列条件就返回为真 |
---|---|
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母a-f,大写字母A-F |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母a-z或A-Z |
isalnum | 字母或者数字,a-z,A-Z,0-9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
如下:
1)//计数器方式
int my_strlen(const char * str)
{
int count = 0;
while(*str)
{
count++;
str++;
}
return count;
}
2)//不创建临时变量的方法,递归实现
int my_strlen(const char * str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
3)//指针-指针的方式,指针相减得到的是他们中间的元素个数
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest&&src); //用assert函数来判断传入的指针是否为空,如果括号内表达式结果为假会直接报错,并显示错误所在文件、行数(要引用头文件),自己以后模拟实现也可以使用此函数判断指针有效性
while((*dest++ = *src++))
{
;
}
return ret;
}
int my_strcmp (const char * src, const char * dst)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
assert(dest&&src);
while(*dest)
{
dest++;
}
while((*dest++ = *src++))
{
;
}
return ret;
}
char * strstr (const char * str1, const char * str2)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s1 && *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
//注:strstr函数的实现还可以用KMP算法更精简的实现,具体内容小伙伴们可以自己去查查,由于篇幅问题这里就不多赘述了,或者俺看看啥时候有时间再补一篇哈
好拉,今天的内容就到这啦,好久没更了有点手生了,大家见谅哈。若发现有误,欢迎评论区指正留言!