1.模拟strlen()实现原理
我们知道定义字符数组时,可以有以下两种形式:
char a[]="abcd";
char a[]={'a','b','c','d'};
两者的区别是第一种末尾会带一个'\0',而第二种不会带,所以可以扫描字符数组每一个字符,如果扫描到'\0',扫描结束
-
具体模拟strlen函数如下:
int my_strlen(char* base) {
int length = 0;
while ((*base++)!='\0') {
length++;
}
return length;
}
当传的是 char a[]="abcd" 这种形式时,会得出正确的结果
当传的是 char a[]={'a','b','c','d'} 这种形式时,会返回一个不确定的值,原因是这种定义下没有'\0'
在对以上进行优化
有可以知道:
while(a) 表示当a!=0时执行循环,其等价于while(a!=0)。
//模拟strlen()函数
int my_strlen(char* base) {
int length = 0;
while (*base++) {
length++;
}
return length;
}
- char a[]={'a','b','c','d'} 这种形式时,返回一个随机值
int my_strlen(char* base) {
int length = 0;
while (*base++) {
length++;
}
return length;
}
int main() {
char ch[] = {'a','b','s','f','2'};
//char ch[] = "afaew";
int length=my_strlen(ch);
int length1 = strlen(ch);
printf("%d\n%d", length,length1);
}
- char a[]="abcd" 这种形式时,返回字符串的长度
int my_strlen(char* base) {
int length = 0;
while (*base++) {
length++;
}
return length;
}
int main() {
//char ch[] = {'a','b','s','f','2'};
char ch[] = "afaew";
int length=my_strlen(ch);
int length1 = strlen(ch);
printf("%d\n%d", length,length1);
}
2.模拟strstr()实现原理
strstr()函数用来检索子串在字符串中首次出现的位置,其原型为:
char *strstr( char *str, char * substr );
返回值:返回字符串str中第一次出现子串的地址;如果没有检索到子串,则返回NULL
char* my_strstr(const char * p1, const char * p2) {
assert(p1);
assert(p2);
char * curr = p1; //用来记录扫描的位置
char * s2 ; //用来扫描第二个字符串
char* s1 ; //用来扫描第一个字符串
if (!(*p1)) {
return p1;
}
while (*curr) {
s1 = curr;
s2 = p2;
//从cur位置,p2位置开始
while ((*s1) && (*s2) && (*s1) == (*s2)) {
s1++;
s2++;
}
//若s2指向为空,则找到返回第一次找到的元素地址
if (!(*s2)) {
return curr;
}
curr++;
}
//找不到返回NULL
return NULL;
}
测试如下:
char* str1 = "hello alibaba !";
char* str2 = "ali";
char* resultadd=my_strstr(str1, str2);
char* primi = strstr(str1, str2);
printf("%s\n%s", resultadd,primi);
输出:
3.模拟strcmp()实现原理
3.1. 函数原型
int strcmp(const char *s1,const char *s2);
3.2.函数功能:比较两个字符串大小
- 当两个字符串相同时,返回0
- 当两个字符串不同时,返回第一对字符不相等时的Ascii码差值
3.3模拟实现如下
int my_strcmp( char* str1, char * str2) {
while ( *str1 == *str2) {
if (!*str1) {
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
int main() {
char* str1 = "abcde";
char* str2 = "dbcde";
int result=my_strcmp(str1, str2);
printf("%d", result);
}
输出:
4.模拟strcpy()实现原理
4.1. 函数原型
char *strcpy(char *dest, const char *src)
4.2.函数功能:把 src 所指向的字符串复制到 dest。
- 需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,会出错
4.3模拟实现如下
char* my_strcpy( char* dest, char* src) {
assert(dest);
assert(src);
char* p1 = dest;
char* p2 = src;
int len = strlen(dest);
while (len) {
*(p1++) = *(p2++);
len--;
}
return p1;
}
int main()
{
char str1[] = "hello";
char str2 []= "world";
char* res=my_strcpy(str1, str2);
printf("%s\n", str1);
}
5.模拟strcat()实现原理
5.1. 函数原型
char *strcat(char *dest, const char *src)
5.2.函数功能:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
- 需要注意的也是如果目标数组 dest 不够大,而源字符串的长度又太长,会出错
5.3模拟实现如下
void my_strcat(char *copStr,char *folStr) {
char* temp = copStr;
while (*temp)
temp++;
while (*folStr)
*temp++ = *folStr++;
return ;
}
int main() {
char copyStr[10] = "abcd" ;
char* p = copyStr;
char* folStr = "efgh";
my_strcat(copyStr, folStr);
while (*p) {
printf("%c", *p++);
}
}
输出:
6.strtok()函数
6.1. 函数原型
char * strtok (char * src, const char * sep);
6.2.函数功能:
- 功能:作用于字符串src,以sep中的字符为分界符,将src切分成一个个子串;如果,src为空值 NULL,则函数保存的指针将在在下一次调用中将作为起始位置。
- 返回值:分隔符匹配到的第一个子串
6.3使用如下
int main() {
char arr[] = "localhost://8080:web/happy.jsp";
char* p = "/:.";
char* result;
for (result = strtok(arr, p); result != NULL; result = strtok(NULL, p) ){
printf("%s\n",result);
}
}
输出:
7.strerror()函数
7.1.函数原型:
char * strerror(int enum);
7.2.函数功能:
- strerror()用来依参数errnum 的错误代码来查询其错误原因的描述字符串, 然后将该字符串指针返回
7.3.返回值:
- 返回描述错误原因的字符串指针
int main() {
FILE* file = fopen("test.txt", "r");
if (!file) {
printf("%s\n", strerror(errno));
}
else {
printf("success!");
}
/*char ch = 'w';
int res = islower(ch);
printf("%d", res);*/
}
当返回指针为空时输出错误码对应的信息: