摘要:四函数字符串追加函数介绍函数的返回值类型为,可以返回被追加的字符串的起始地址。利用函数所需的头文件函数的使用代码运行结果为函数的特点及注意事项源字符串必须以结束。目标空间必须有足够的大,能容纳下源字符串的内容。
strlen函数是用于求字符串长度的(不包括/0),例如字符串“abc”的长度为3,在代码中我们如何使用strlen函数呢?
#include int main(){ const char*str1 = "abcdef"; const char*str2 = "bbb"; if(strlen(str2)-strlen(str1)>0) { printf("str2>str1/n"); } else { printf("srt1>str2/n"); } return 0; }
程序结果如图:
我们的程序的结果可能会感到吃惊,字符串str2的长度为3,字符串str1的长度为6,那为什么最后打印的却是str2>str1呢?
经过查阅资料发现,strlen函数返回值的类型为size_t(无符号整型),因此无符号整型之间的运算结果仍然是无符号整型。3-6的确等于-3,而最终打印的是-3的补码,而-3是二进制原码得到的。-3的原码为10000000000000000000000000000011而-3的补码为01111111111111111111111111111101,是个正数,因此strlen(str2)-strlen(str1)的结果是大于0的。
strlen的特点及注意事项:
方法一:计数器法
#include #include int my_strlen(const char* str){ int count = 0; while (*str++!="/0") { count++; } return count;}int main(){ char* str1 = "abcdef"; int ret = my_strlen(str1); printf("%d", ret); return 0;}
代码运行结果:(以下的运行结果跟下图一致)
方法二:递归方法
#include #include int my_strlen(const char* str){ if(*str == "/0") return 0; else return 1+my_strlen(str+1);}int main(){ char* str = "abcdef"; int ret = my_strlen(str); printf("%d", ret); return 0;}
方法三:指针减指针的方式
int my_strlen(char *s) { char *p = s; while(*p != ‘/0’ ) p++; return p-s; }int main(){ char* str = "abcdef"; int ret = my_strlen(str); printf("%d", ret); return 0;}
先看strcpy函数的返回值类型与传值。
查阅资料我们可以看到,strcpy函数传入的第一个参数为目标地址处,第二个参数为源地址处,返回值类型为char*类型。
例如以下代码:
#include #include int main(){ char str1[20] = "abcdef"; char str2[] = "zjr"; strcpy(str1, str2); printf("%s", str1); return 0;}
代码执行结果如图:
strpy函数的特点及注意事项:
char *my_strcpy(char *dest, const char*src){ char *ret = dest; assert(dest != NULL); assert(src != NULL); while((*dest++ = *src++)) { ; } return ret;}#include #include int main(){ char str1[20] = "abcdef"; char str2[] = "zjr"; my_strcpy(str1, str2); printf("%s", str1); return 0;}
在my_strcpy函数的形参中的源字符串地址使用了const的原因是:保证修改的是目的地字符串的内容而不是源字符串的内容。my_strcpy函数内部使用了assert函数的目的是保证传入的目的地字符串地址与源字符串地址都不为空指针,如果为空指针则程序代码执行时会报错。
如上代码运行结果为:
简单介绍下assert函数:
头文件为assert.h
传入的为空指针就会报错,否则不影响程序执行。
strcat函数的返回值类型为char*,可以返回被追加的字符串的起始地址。而第一个参数为目的地字符串的地址,第二个参数为源字符串的地址。
利用strcat函数所需的头文件:
strcat函数的使用:
#include #include int main(){ char str1[20] = "abcd"; char str2[] = "efgh"; char* ret = strcat(str1, str2); printf("%s", ret); return 0;}
代码运行结果为:
strcat函数的特点及注意事项:
char *my_strcat(char *dest, const char*src)//保证源字符串不被修改 { char *ret = dest; assert(dest != NULL); assert(src != NULL); while(*dest) { dest++;//先到目的地字符串的/0地址处 } while((*dest++ = *src++))//先解引用后++,因此最后能将源字符串内的/0也追加进去 { ; } return ret; }#include #include int main(){ char str1[20] = "abcd"; char str2[] = "efgh"; char* ret = my_strcat(str1, str2); printf("%s", ret); return 0;}
代码执行结果:
strcmp函数的返回值类型为int,第一个参数为一个字符串首字母的地址,第二个参数为另一个字符串首字母的地址,依次往后作比较,这strcmp函数比较的是字符串的内容,而不是字符串的长度。
对于strcmp函数的返回值,C语言规定如果第一个字符串的内容小于第二个字符串的内容,则返回小于0的值;如果第一个字符串的内容等于第二个字符串的内容,则返回0,如果第一个字符串的内容大于第二个字符串的内容,则返回大于0的值。
#include #include int main(){ char str1[] = "abcd"; char str2[] = "abc"; int ret = strcmp(str1, str2); printf("%d", ret); return 0;}
代码运行结果:(结果虽然返回大于0的值都为1,但是每个编译器此处规定返回大于0的值有所不同,此处会有差异)。
假如以上例子对strcmp函数是比较字符串内容不够清晰,以下例子能更好地观察:
#include #include int main(){ char str1[] = "abcd"; char str2[] = "abq"; int ret = strcmp(str1, str2); printf("%d", ret); return 0;}
代码运行结果:
#include #include my_strcmp(const char* s1, const char* s2){ assert(s1 && s2); while (*s1 == *s2) { if (*s1 == "/0") return 0; s1++; s2++; } return *s1 - *s2;//比较字符串内容}#include int main(){ char str1[] = "abcd"; char str2[] = "abq"; int ret = my_strcmp(str1, str2); printf("%d", ret); return 0;}
代码运行结果:
strcpy、strcat、strcmp
都是长度不受限制的字符串函数,所以就显得不够安全。所以就有了strncpy、strncat、strncmp
函数。
strncpy函数的返回值类型为char*类型,该函数第一个参数为目的地字符串的首字母地址,第二个参数为源字符串的首字母地址,第三个参数为需要拷贝过去的字符个数。
使用strncpy函数所需的头文件:
strncpy的使用:
#include #include int main(){ char str1[20] = "abcd"; char str2[] = "kpl"; char* ret = strncpy(str1, str2, 2); printf("%s", ret); return 0;}
代码运行结果:
#include #include char* my_strncpy(char* dest, char* src, size_t count){ while (count--)//先使用count再减1 { *(dest + count) = *(src + count); } return dest;}int main(){ char str1[20] = "abcd"; char str2[] = "kpl"; char* ret = my_strncpy(str1, str2, 2); printf("%s", ret); return 0;}
strncat函数与其他的受限制的库函数的返回值类型与参数几乎一样,此处不再进行说明。
使用strncat函数所需头文件:
#include #include #include char* my_strncat(char* dest, char* src, size_t count){ assert(dest && src); char* ret = dest; while (*dest) { dest++;//到目的地字符串的/0位置 } while (count--) { *(dest + count) = *(src + count);//字符串追加 } return ret;}int main(){ char str1[20] = "abcd"; char str2[] = "kpl"; char* ret = my_strncat(str1, str2, 2); printf("%s", ret); return 0;}
strncmp函数的返回值类型为int型,返回值的规则跟strcmp函数相同,此处不再细讲。第一个与第二个参数:因为两个字符串只是用来作比较,如果修改则不满足strncmp函数的使用规则,因此在前面两个参数前面加上const保证字符串内容不被修改。第三个参数为比较的字符个数。
使用strncmp函数所需的头文件:
strncmp函数的使用:
#include #include int main(){ char str1[] = "abcd"; char str2[] = "abkl"; int ret = strncmp(str1, str2, 2); printf("%d", ret); return 0;}
代码运行结果:
#include #include #include int my_strncmp(char* s1, char* s2, size_t count){ assert(s1 && s2); while (count--) { if (*s1 == *s2) { s1++; s2++; } } return *s1 - *s2;}int main(){ char str1[] = "abcd"; char str2[] = "abkl"; int ret = my_strncmp(str1, str2, 2); printf("%d", ret); return 0;}
代码执行结果:
strstr函数的返回值类型为char类型,第一个参数是被查找的字符串,第二个参数是在第一个参数中需要查找的字符串。例如:第一个字符串为i am a student,第二个字符串为a,则返回的char类型用字符串形式打印的结果为am a student 。
使用strstr函数所需的头文件:
strstr函数的使用:
#include #include int main(){ char str1[] = "abcdefdgh"; char str2[] = "d"; char* ret = strstr(str1, str2); printf("%s", ret); return 0;}
代码执行结果:
#include #include char* my_strstr(const char* str1, const char* str2){ char* s1, * s2; char* cp = str1; if (*str2 == "/0") { return str1; } while (*cp) { s1 = cp; s2 = str2; while (*s1 && *s2 && *s1 == *s2)//开始遍历寻找 { s1++; s2++; } if (*s2 == "/0") { return cp; } cp++;//当字符查找途中发现有不相同的字符,则从刚开始查找处的下一个字符开始查找 } return NULL;}int main(){