描述:C语言中对于字符串类型并未定义,但存在许多有关字符串的库函数(如:strstr(在原串中匹配子串),strcpy(将原串内容拷贝到目标串中),strcmp(比较两个字符串的内容),strcat(连接两个字符串,亦为字符串的追加),strlen(求取字符串的长度)....),我们可以自己编写程序实现以上功能的函数,而不调用库函数,,,再对照库函数进行学习,有利于提高自身的编程能力。本文章中对于main函数省略不写,读者可自主编写测试用例进行测试。
//★1.strcat函数(连接两个字符串,亦为字符串的追加) #include<stdio.h> #include<stdlib.h> #include<assert.h> char *my_strcat(char *arr1, const char *arr2) { assert(arr1); assert(arr2); char *ret = arr1; while (*ret) { ret++; //ret指针不断移动,直至位于arr1数组的‘\0’处 } while (*ret++ = *arr2++) //不断将arr2数组的内容追加到arr1中,注:(arr1中的‘\0’会被arr2中的第一个字符覆盖,最后arr2中的‘\0’被追加到arr1的末尾位置,否则数组中没有结束标志) { ; } return arr1; }
//★2.strcpy函数(将原串内容拷贝到目标串中) #include<stdio.h> #include<stdlib.h> #include<assert.h> char *my_strcpy(char *dest, const char *src) { assert(dest); assert(src); char *ret = dest; while (*ret++ = *src++) //不断将原串的内容拷贝到目标串中,若将指针的移动置于循环体内,要注意最后的‘\0’字符要追加在末尾处 { ; } return dest; }
//★3.strstr函数(在原串中匹配子串) #include<stdio.h> #include<stdlib.h> #include<assert.h> char *my_strstr(char *src, char *dst) { assert(dst); assert(src); char *p = src; char *q = dst; while ((*dst) && (*src)) { if (*src == *dst) //两指针内容相等时,指针向后移动不断匹配 { src++; dst++; } else { src = ++p; //指针内容不等时,子串指针跳至首地址,原串返回到此次匹配开始的下一位置 dst = q; p = src; } } if (*dst == '\0') //子串为'\0'时,说明匹配完成,返回原串与子串相同的首地址处 { return p; } else { return NULL; //没有匹配项,返回空 } }
//★4.strlen函数(求取字符串的长度,此处有三种做法) #include<stdio.h> #include<stdlib.h> #include<assert.h> //①.计数器计数字符串长度 int my_strlen(const char *str) { assert(str); int count = 0; while (*str++) { count++; } return count; } //②.递归调用1+函数本身(指针不断偏移) int my_strlen(const char *str) { assert(str); int num = 0; while (*str) { return num = (1 + my_strlen(str + 1)); } return num; } //③.指针末位置减去指针初始位置再减一(末位置为‘\0’) int my_strlen(const char *str) { assert(str); char *pre = str; while (*pre++) { ; } return (pre - str - 1); }
//★5.strcmp函数(比较两个字符串的内容,此处有两种做法,大体上很相似,最大区别为一个方法返回0,-1,1这三种值,另一个方法返回的是0,或者为两个串中不同字符的差值) #include<stdio.h> #include<stdlib.h> #include<assert.h> //①.返回值为0,-1,1的方法实现 int my_strcmp(const char *str1, const char *str2) { assert(str1); assert(str2); while (*str1 == *str2) //循环执行的条件为两个指针所指向的内容相同 { if (*str1 == '\0') //若有一个指针指向了‘\0’,则另一个也为‘\0’,说明两串相同,返回0 { return (0); } str1++; str2++; } if ((*str1 - *str2) > 0) //跳出循环的条件为存在不同字符,则分别处理返回值 return (1); else return (-1); } //②.返回值为0,或者为两个串中不同字符的差值 int my_strcmp(const char *str1, const char *str2) { assert((str1) && (str2)); while ((*str1) && (*str2)) //循环执行的条件为str1和str2都不为‘\0’结束标志 { if (*str1 == *str2) //如果两指针指向的内容相同,则指针分别移动 { str1++; str2++; } else return *(unsigned char *)(str1)-*(unsigned char *)(str2); //如果两指针指向的内容不同,则返回两字符的差值,因为char在vs2013中与有符号的char保持一致,所以其能表示的最大正值为127,最小负值为-128,但由ascII码表可知有256中字符,所以产生的差值会溢出,无法正确表示,所以将其转化为unsigned char的形式 } if ((*str1 == *str2) && (*str1 == '\0')) //跳出循环的条件为两字符串中至少有一指针移动至‘\0’处,如果两个指针都指向‘\0’返回0,否则返回两字符的差值 { return 0; } else { return *(unsigned char *)(str1)-*(unsigned char *)(str2); } return -1; //函数最后要有一个返回值,但无其他异常情况,返回一个-1即可 }
※注:对于与内存有关的处理函数(例如内存块的复制,移动覆盖,重置等)将在后续博文中慢慢整理,本人C语言新手一枚,还望各网友大神们的多多指点,不吝赐教。