strlen函数
size_t strlen ( const char * str );
返回类型为size_t,参数类型为char *
注意事项:
1.字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
2.参数指向的字符串必须要以 '\0' 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )
int main() { char a[] = "123456"; printf("%d",strlen(a)); return 0; }
由于返回值是无符号整形,所以这里str2>str1,俩个无符号整形相加减结果还是无符号整形
strlen模拟
#include<stdio.h> #include<assert.h> size_t my_strlen(const char* arr) { assert(arr != NULL); size_t a = 0; while (*arr++ != '\0') { a++; } return a; } int main() { char arr[] = "abcde"; size_t n = my_strlen(arr); printf("%d", n); return 0; }
strcpy函数
char* strcpy(char * destination, const char * source);
用源里面的内容覆盖目标里面的内容 ,返回类型为char *,参数类型为char *,返回值为目标字符串(目标空间的起始地址)
注意事项:
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变
该函数在遇到源内容里面的\0时,会停止获取\0后面的字符,并将\0和\0之前的内容拷贝到目标地址里(这个是具有覆盖功能的)
这种情况下调试会报错,因为字符串常量不能被修改
strcpy模拟
#include<stdio.h> #include<assert.h> char* my_strcpy(char* des,const char* sour) { assert(des&&sour); char* tmp = des; while (*des++ = *sour++) { ; } return tmp; } int main() { char arr1[] = "abcdef"; char arr2[20] = {0}; my_strcpy(arr2,arr1); printf("%s", arr2); return 0; }
strcat函数
char * strcat ( char * destination, const char * source );
返回值为目标空间的起始地址,返回类型为char *,参数类型为char * ,该函数为字符串追加函数
注意事项:
源字符串必须以 '\0' 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
这个在追加时,遇到源字符串里的\0,会将\0和\0之前的字符追加到目标字符串里
strcat模拟
#include<stdio.h> #include<assert.h> char* my_strcat(char *dest,const char *sorc) { assert(dest && sorc); char* tmp = dest; while (*dest != '\0') { dest++; }//找到目标字符串里的\0 while (*dest++ = *sorc++) { ; } return tmp; } int main() { char arr1[20] = "hello "; my_strcat(arr1,"world"); printf("%s", arr1); return 0; }
strcat函数能否自我追加
答案是不行,原因如下:
strcmp函数
int strcmp ( const char * str1, const char * str2 );
返回类型为int,参数为char *
str1
str1=str2,返回0
str1>str2,返回大于0的数
这个函数是如何进行比较的?
a和a比较,ASCII码值相等,然后比较下一个字符
b和b比较,ASCII码值相等,然后比较下一个字符
c和c比较,ASCII码值相等,然后比较下一个字符
d和\0比较,d的ASCII码值大于\0的ASCII码值,然后返回一个>0的数字
注意:strcmp是从放第一个字符开始比较ASCII码值,若不相等,则会结束,strcmp不是比较字符串长度的
模拟实现strcmp函数
#include<stdio.h> #include<assert.h> int my_strcmp(const char* arr1, const char* arr2) { assert(arr1 && arr2); while (*arr1!='\0'&& * arr1 == *arr2) { arr1++; arr2++; } return (*arr1 - *arr2); } int main() { char arr1[] = "abc"; char arr2[] = "abcdefg"; int c=my_strcmp(arr1, arr2); if (c > 0) printf(">"); else if (c == 0) printf("="); else printf("<"); return 0; }
strncpy函数
char * strncpy ( char * destination, const char * source, size_t num );
跟strcpy一样,只不过多了一个参数,返回值类型为 char *,返回值为目标起始地址
,这个参数是用来限制拷贝字节数的。
拷贝过程中,若遇到\0,则会跟\0一起拷贝过去
如果拷贝的时候,源字符串个数不够,则会补充\0
strncat函数
char * strncat ( char * destination, const char * source, size_t num );
返回值类型为char *,返回值为目标首地址,与strcat相比,多了一个参数,这个参数是用来限制被追加的字节数的
通过这个,我们可以看到在追加结束时,函数会自动补一个\0
strnmcp函数
int strncmp ( const char * str1, const char * str2, size_t num );
返回值类型为int,多了一个参数,这个参数是用来限制str2的字节个数的,这个函数也是比较ASCII码值,而不是比较字符串长度
这里值比较了arr2的前三个字符
strstr函数(查找子串函数)
char * strstr ( const char *str1, const char * str2);
返回值为类型为char *,参数类型为char *
这是查找str1里面有没有出现str2这个字符串,str2作为字串,如果在str1里面找到了子串,则返回子串在母串里的第一个字符的地址,如果没有找到子串,则返回空指针NULL
这里我们可以看到,返回的是子串在母串中的起始位置
strstr函数模拟实现
char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); char* s1 = str1; char* s2 = str2; char* p = str1; while (*p) { s1 = p; s2 = str2; while (*s1 == *s2&&*s1!='\0'&&*s2!='\0') { s1++; s2++; } if (*s2 == '\0') return p; p++; } return NULL; } int main() { char str1[] = "132456879"; char str2[] = "56"; char *ret=my_strstr(str1, str2); printf("%s", ret); return 0; }