本篇博客介绍一些函数和如何模拟实现
strlen
函数
介绍:计算字符串 str 的长度,直到空结束字符,但不包括空结束字符
原型:size_t strlen(const char *str)
返回值:返回字符串的长度
注意点:
1.字符串是以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
2. 参数指向的字符串必须要以 ‘\0’ 结束。 注意函数的返回值为 size_t是无符号的。
模拟实现strlen
函数
常用递归和指针-指针的方法
1.递归
#include<stdio.h>
//递归实现 //递归无非两步 初始条件和逼近条件
int my_strlen(char *str)
{
if(*str=='\0') //如果数组为'\0'就返回0
return 0;
else
return 1+my_strlen(str+1); //不是'\0 1 + 指针+1 指向后一个元素
}
int main()
{
char arr[]="bite";
printf("%d",my_strlen(arr));
return 0;
}
2.指针-指针
指针-指针=指针中间元素个数
#include<stdio.h>
int my_strlen(char *str)
{
char*begin=str; //记录指针初始位置
while(*str!='\0')
str++; //循环记录str到'\0'之前的位置
return str - begin;
}
int main()
{
char arr[]="bite";
printf("%d",my_strlen(arr));
return 0;
}
strcpy
函数 VS stcnpy
函数
char *strcpy(char *dest(接收被复制字符串), const char *src(被复制字符串))
把src所指向的字符串复制到 dest。
模拟实现strcpy函数
#include<stdio.h>
int main()
{
char arr1[]="bite";
char arr2[10]={0}
char *dest=arr1; //把arr1首元素赋值给dest指针
char *sec=arr2; //把arr2首元素赋值给sec指针
while(*sec++=*dest++) // *优先级高于++
{ //先把'b'赋给sec …………
; //到'\0' 会先赋值给sec然后才进行判断 因为while('\0')为假就不会往后
}
printf("%s",arr2);
return 0;
}
char * strncpy ( char * destination, const char * source, size_t num )
区别是strncpy可以指定需要复制多少个字符
如何理解第二句话
例子
#pragma warning(disable : 4996)
#include<stdio.h>
#include<string.h>
int main()
{
char a[20] = "bite666666";
char b[] ="peng";
strncpy(a,b,6); //把b中6个字符复制到a 可以知道b只有5个元素 小于num 所以会补0
return 0;
}
可以看到这里第6个元素a[5]赋成’\0’
strcat
VS strncat
char * strcat ( char * destination, const char * source )
把scource接到destination后面并在scource最后补’\0’
注意:
char * strncat ( char * destination, const char * source, size_t num );
把scource中的num个字符接到destination后面并在scource最后补’\0’
模拟实现strcat
函数
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
while(*dest)
{
dest++;
}
while(*dest++ = *src++)
{
;
}
return ret;
}
strcmp
VS strncmp
strcmp函数功能是进行两个字符串的比较
函数原型: int strcmp ( const char * str1, const char * str2 )
函数原型:int strncmp ( const char * str1, const char * str2, size_t num );
比较字符串的前n个字符
str1, str2 为需要比较的两个字符串,num为要比较的字符的数目
模拟实现strcmp
原理: 字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值
int my_strcmp(const char *str1,const char *str2)
{
while(str1 == str2) //如果两个字符相同就++向后比
{
if(str1=='\0' &&str2 =='\0')
return 0;
str1++;
str2++;
}
return *str1 -*str2; //返回的是ASCII码值 如果 *str1 -*str2 >0 就说明str1>str2 反之str1<str2
strstr
函数
作用:检索子串在字符串中首次出现的位置
char * strstr ( const char *str1, const char * str2)
检测str2有没有出现在str1中
返回字符串str1中第一次出现子串str2的地址;如果没有检索到子串,则返回NULL
#include<stdio.h>
#include<string.h>
int main()
{
char *str1 = "bite is good";
char *str2 = "is";
char *s = strstr(str1, str2);
printf("%s\n", s);
return 0;
}
模拟实现strstr
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
char* s1 = NULL;
char* s2 = NULL;
char* cp = (char*)str1; //把str1赋给cp让cp去遍历并记住位置
while (*cp) //cp遍历str1
{
s1 = cp; //s1去接收每次要比较的字符
s2 = (char*)str2; //s2去接收要和s1比的内容
while (*s1 == *s2 && *s1 && *s2) //找到一样的 并且都不等于斜杠0
{
s1++; //s1和s2 都++ 向后去比较下一个
s2++;
if (*s2 == '\0') //当s2为\0 说明比较完成返回比较的地址
return cp;
}
cp++; //当s1和s2 不等 cp++ 向后指向下一个字符去比较
}
return NULL;
}
/*例子 str1=“saatg” str2="at" 结果是atg
1. cp='s' s1='s' s2='a' while (*s1 == *s2 && *s1 && *s2)不成立
2. cp++ cp='a' s1='a' s2='a' while (*s1 == *s2 && *s1 && *s2)成立
s1++ s2++ s1='a' s2='t' if (*s2 == '\0')不成立
3. 继续循环while (*s1 == *s2 && *s1 && *s2) s1 ='a' != s2='t' 不成立 cp++
4. cp='a' s1='a' s2='a' while (*s1 == *s2 && *s1 && *s2)成立
s1++ s2++ s1='t' s2='t' if (*s2 == '\0')成立
5.继续while s1=t s2=t 相等成立 s1++ s2++ s1='g' s2='\0' if (*s2 == '\0')不成立
6.return cp 此时cp返回第二个'a'的地址
strerror
作用:返回错误原因的描述字符串
char * strerror ( int errnum )
strerror()用来依参数errnum 的错误代码来查询其错误原因的描述字符串, 然后将该字符串指针返回
个人觉得没有比perror
函数好用
int main()
{
FILE*pf=fopen("test1","r");
if(pf = NULL)
{
perror("fopen");
return 1;
}
return 0;
}
perror( ) //括号填要输出的字