1,strlen函数:计算字符串长度
size_t strlen( const char *string );
首先来看strlen函数的描述:它的参数是一个字符串,返回值是一个无符号数;
所以我们来尝试实现这个函数
1)利用循环来实现
字符串都是以'\0'结束的,我们由此可以得到一个实现strlen的函数
int my_strlen(char* str) { int count = 0; while (*str) { count++; str++; } return count; }
用*str接受字符串的地址,然后每碰到一个不为'\0'的字母则count+1;
2)利用递归来实现
int my_strlen(char* str) { if (*(str+1)) { return 1 + my_strlen(str + 1); } else { return 1; } }
递归至*(str+1)=='\0'的时候终止递归;
3)利用指针实现
int my_strlen(char* str) { char* left = str; char* right = str; while (*right) { right++; } return right - left; }
用left指向第一个字符的位置,然后用right找到最后一个字母的位置;
然后该两个指针之差就是字符的个数,这里需要知道,指针-指针得到的是这两个指针指向的地址之间,有该指针类型的个数。
2.strcpy函数:拷贝字符串
char *strcpy( char *strDestination, const char *strSource );
由函数介绍可得
该函数的两个参数:1)第一个参数是目标地址,2)第二个参数是源地址且源地址的值不可被改变。3)返回参数是一个字符指针
该函数的功能
1)源字符串必须以'\0'结束;
2)会将源字符串中的'\0'也拷贝过去;
3)目标空间必须足够大以确保能够存放源字符串;
4) 目标空间的值必须可变。
现在来看实现方法
char* my_strcpy(char* str1,const char* str2) { char* ret = str1; while (*str1 = *str2) { str1++; str2++; } return ret; }
分析代码:
1)分别用str1,str2接收目的地址和源地址;
2)用ret标记str1用来最后进行返回;
3)先将*str2的值赋给*str1;然后判断该值是否为'\0',这样可以保证将'\0'也传给目的地址;
3)进行下一个字符的传值。
该代码可以改进成
char* my_strcat(char* str1, char* str2) { char* ret = str1; while (*str1++ = *str2++) { ; } return ret; }
3,strcat函数:追加字符串
char *strcat( char *strDestination, const char *strSource );
分析函数说明:1)第一个接收参数是目的字符串地址2)第二个接收参数是一个源字符串地址,且地址的值不可被更改。3)返回参数是一个字符指针
该函数特点
1)源字符串必须以'\0'结束;
2)目标空间必须足够大,足以容纳下包括目标地址和源地址的所有字符串;
3)目标空间的值必须可变。
模拟实现
char* my_strcat(char* str1, char* str2) { char* ret = str1; while (*str1) { str1++; } while (*str1++ = *str2++) { ; } return ret; }
分析代码
1)第一段判断*str1是否为'\0'来找到目标地址原字符串最后一个值;
2)接下来就是将源字符串拷贝过来,实现方法与strcpy类似,注意这里源字符串将目标地址字符串中的'\0'也替换了。
3.strcmp字符串比较
int strcmp( const char *string1, const char *string2 );
分析函数说明1)接收的两个参数都是不可变的两个字符串的地址,2)返回值是一个int类型的数据
函数功能
1)第一个字符串大于第二个字符串的时候返回1;
2)第一个字符串等于第二个字符串的时候返回0;
3)第一个字符串小于第二个字符串的时候返回-1;
注:不同的系统可能有不同的情况
模拟实现
int my_strcmp(char* str1, char* str2) { while (*str1 == *str2) { if (!*str1) { return 0; } str1++; str2++; } if (*str1 > *str2) return 1; else return -1; }
代码分析:
1)当两者相等的时候则通过判断第一个字符串是否为'\0'来判断比较是否结束,如果比较结束则两者完全相等返回0;
2)当两者不同时如果前者比后者大则返回1;
3)如果前者比后者小则返回-1。
5,strncpy:拷贝指定个数的字符
char *strncpy( char *strDest, const char *strSource, size_t count );
比strcpy多了个指数count
函数功能:用指定个数的源地址字符串替代目标地址中的字符串;
模拟实现
char* my_strncpy(char* str1, char* str2, size_t n) { char* ret = str1; while (n) { *str1 = *str2; str1++; str2++; n--; } return ret; }
代码分析:和strcpy相比,用n作为循环的条件,当n为0的时候则退出循环。
6. strncat:追加源字符串中指定个数的字符
char *strncat( char *strDest, const char *strSource, size_t count );
比strcat多了个指数count
模拟实现
char* my_strncat(char* str1, char* str2, size_t n) { char* ret = str1; while (*str1) { str1++; } while (n) { *str1++ = *str2++; n--; } return ret; }
代码分析:和strcat相比就是第二个循环的条件变成了n,以确保替换n个字符后停止替换
7.strncmp:比较字符串中指定个数的字符
int strncmp( const char *string1, const char *string2, size_t count );
比strcmp多了个指数count
模拟实现
int my_strncmp(char* str1, char* str2, size_t n) { while (n--) { if (*str1 == *str2) { str1++; str2++; continue; } if (*str1 > *str2) return 1; else return -1; } return 0; }
代码分析:
1)当n不等于0的时候进入循环然后判断两个字符串的字符是否相等,如果相等则跳出循环比较下一个字符,n-1;
2)如果不等则比较两者的大小,如果前者大则返回1,后者大则返回-1;
3)如果n==0,则说明已经比较完所需的字符个数,且以比较的字符相等。
8,strstr,查找字符串
char *strstr( const char *string, const char *strCharSet );
分析:第一个参数是被查找的字符串,第二个参数是要查找的字符串:即检查第一个字符串中是否包含第二个字符串。
特点:1)如果不存在就返回NULL;2)存在就返回第一次出现该字符串的地址
模拟实现:
#include<stdio.h> char* my_strstr(char* ptr1, char* ptr2) { char* src = ptr1; while (*src) { char* s1 = src; char* s2 = ptr2; while (*s1 && *s2 && (*s1 == *s2)) { s1++; s2++; } if (!*s2) { return src; } src++; } return NULL; } int main() { char arr1[] = "abcdef"; char arr2[] = "def"; printf("%s", my_strstr(arr1, arr2)); return 0; }
代码分析:
1)用指针src记录字符比较的起始位置,然后用指针str1指向被查找字符串的位置,用str2指向要查找的字符串的比较位置;
2)如果比较失败则比较的起始位置向后移一位即src++,str1指向起始位置,str2回到要查找的字符串的第一个字符然后重新比较,失败则重复上述步骤。
9,strtok:分离分隔符
char *strtok( char *strToken, const char *strDelimit );
分析:第一个参数是被分离的字符串,第二个参数是分隔符号;
函数特点:
1)sep参数是个字符串,定义了用作分隔符的字符集合;
2)第一个参数指定一个字符串,它包含了0个或者多个sep字符串中一个或者多个分隔符分割的标记;
3)strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针;
(strtok函数会改变被操作的字符串,所以在使用strtok切分的字符串一般都是临时拷贝的内容并且可以被修改);
4)strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置;
5)strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始查找下一个标记;
6)如果字符串中不存在更多的标记则会返回NULL指针。
使用举例:
10.strerror:返回错误码对应的错误信息
char *strerror( int errnum );
错误码 错误信息
0 No error
1 Opration not pertted
2 No such file or directort