//关于string的一些库函数的实现 //strncpy char *_strncpy(char *strDes, const char *strSrc, unsigned int count) { assert(strDes != NULL && strSrc != NULL); char *address = strDes; while (count-- && *strSrc != '\0') *strDes++ = *strSrc; *strDes = '\0'; return address; } //strchr //查找字符串s中首次出现字符c的位置 char *_strchr(const char *str, int c) { assert(str != NULL); for (; *str != (char)c; ++str) { if (*str == '\0') return NULL; return str; } } //strcmp int _strcmp(const char *s, const char *t) { assert(s != NULL && t != NULL); while (*s && *t && *s == *t) { ++s; ++t; } return (*s - *t); } //strncmp /* int strncmp(char *str1, char *str2, int maxlen); * 比较字符串str1和str2的前maxlen个字符。如果前maxlen字节完全相等,返回值就=0; * 在前maxlen字节比较过程中,如果出现str1[n]与str2[n]不等,则返回(str1[n]-str2[n])。 */ int _strncmp(const char *s, const char *t, unsigned int count) { assert(s != NULL && t != NULL); while (*s && *t && *s == *t && count--) { ++s; ++t; } return (*s - *t); } //strcat char *_strcat(char *strDes, const char *strSrc) { assert(strDes != NULL && strSrc != NULL); char *address = strDes; while (*strDes != '\0') ++strDes; while ((*strDes++ = *strSrc++) != '\0') NULL; return address; } //strncat /*原型:extern char *strncat(char *dest,char *src,int n); *用法:#include <string.h> *功能:把src所指字符串的前n个字符添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。 *说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 */ char *_strncat(char *strDes, const char *strSrc, unsigned int count) { assert(strDes != NULL && strSrc != NULL); char *address = strDes; while (*strDes != '\0') ++strDes; while (count-- && *strSrc != '\0') *strDes++ = *strSrc++; *strDes = '\0'; return address; } //strlen int _strlen(const char *str) { assert(str != NULL); int len = 0; while (*str++ != '\0') ++len; return len; } //strdup //将字符串复制到新的位置 char *_strdup(char *strSrc) { if (strSrc != NULL) { char *start = strSrc; int len = 0; while (*strSrc++ != '\0') ++len; //分配新内存 char *address = (char *)malloc(len + 1); assert(address != NULL); while ((*address++ = *start++) != '\0') return address - (len + 1); //指针返回到首地址 } return NULL; } //strstr //从字符串str1中查找是否有符串str2,如果有,从str1中的str2位置起,返回str1的指针,如果没有,返回null。 char *_strstr(const char *strSrc, char *str) { assert(strSrc != NULL && str != NULL); const char *s = strSrc; const char *t = str; for (; *strSrc != '\0'; ++strSrc) { for (s = strSrc, t = str; *s == *t && *t != '\0'; ++s, ++t) NULL; if (*t == '\0') return (char *)strSrc; } return NULL; } //strpbrk /*原型:extern char *strpbrk(char *s1, char *s2); *依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时, *则停止检验,并返回该字符位置,空字符NULL不包括在内。 *==>在源字符串(s1)中找出最先含有搜索字符串(s2)中任一字符的位置并返回,若找不到则返回空指针。 */ char *_strpbrk(const char *strSrc, const char *str) { assert(strSrc != NULL && str != NULL); const char *s; while (*strSrc != '\0') { s = str; while (*s != '\0') { if (*strSrc == *s) return (char *)strSrc; ++s; } ++strSrc; } return NULL; } char *_strprbk(const char *str1, const char *str2) { const s1,s2; for (s1 = str1; *s1 != '\0'; ++s1) { for (s2 = str2; *s2 != '\0'; ++s2) { if (*s1 == *s2) return (char *)s1; } } return NULL; } //strcspn /*原型:size_t strcspn(const char *s1,const char *s2); *功能:顺序在字符串s1中搜寻与s2中字符的第一个相同字符,包括结束符NULL, *返回这个字符在S1中第一次出现的位置。 */ /*strpbrk和strcspn这两个函数功能相似, *区别在于前者返回的是一个指针,而后而返回的是一个数组下标值, *或者可以前者为绝对值,而后者为偏移量 */ int *_strcspn(const char *strSrc, const char *str) { assert(strSrc != NULL && str != NULL); const char *t = strSrc; const char *s; while (*t != '\0') { s = str while (*s != '\0') { if (*t == *s) return t - strSrc; ++s; } ++t; } return 0; } //strspn /*size_t strspn (const char *s,const char * accept); *(返回字符串中第一个不在指定字符串中出现的字符下标) */ int _strspn(const char *strSrc, const char *str) { assert(strSrc != NULL && str != str); const char *t = strSrc; const char *s; while (*t != '\0') { s = str; while (*s != '\0') { if (*t == *s) break; ++s; } if (*s == '\0') return t - strSrc; ++t; } } int _strspn_(const char *s, const char *accept) { const char *p; const char *a; int count = 0; for (p = s; *p != '\0'; ++p) { for (a = accept; *a != '\0'; ++a) { if (*p == *a) break; } if (*a == '\0') return count; ++count; } return count; } //strrchr /*原型:char *strrchr(char *str, char c); *功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置), * 并返回从字符串中的这个位置起,一直到字符串结束的所有字符。如果未能找到指定字符,那么函数将返回NULL。 */ char *_strrchr(const char *str, int c) { assert(str != NULL); const char *s; while (*s != '\0') ++s; for (--s; *s != (char) c; --s) { if (s ==str) return NULL; return (char *)s; } } //strrev /*原型:extern char *strrev(char *s); *功能:把字符串s的所有字符的顺序颠倒过来(不包括空字符NULL) */ char *_strrev(char *str) { char *s = str, *t = str, c; while (*t != '\0') ++t; for (--t; s < t; ++s, --t) { c = *t; *t = *s; *s = c; } return str; } //strnset /* *原型: char *strnset(char *str, char ch, unsigned n); *功能: 将一个串中的前n个字符都设为指定字符ch */ char *_strnset(char *str, int c, unsigned int count) { assert(str != NULL); char *s = str; for (; *s != '\0' && s - str < count; ++s) *s = (char) c; return str; } /*函数:strset *原型:extern char *strset(char *s, char c); *功能:把字符串s中的所有字符都设置成字符c */ char *_strset(char *str, int c) { assert(str != NULL); char *s = str; for (; *s != '\0'; ++s) *s = (char) c; return str; } /*函数:strupr *原型:extern char *strupr(char *s); *功能:将字符串s转换为大写形式 *说明:只转换s中出现的小写字母,不改变其它字符。返回指向s的指针 */ char *_strupr(char *str) { assert(str != NULL); char *s = str; while (*s != '\0') { if (*s >= 'a' && *s <= 'z') *s -= 0x20; s++; } return str; } /*函数:strlwr *原型:extern char *strlwr(char *s); *功能:将字符串s转换为小写形式 *说明:只转换s中出现的大写字母,不改变其它字符。返回指向s的指针。 */ char *_strlwr(char *str) { assert(str != NULL); char *s = str; while (*s != '\0') { if (*s >= 'A' && *s <= 'Z') *s += 0x20; s++; } return str; } /*函数:strtok *原型:char *strtok(char s[], const char *delim); *功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。 * *说明:strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串, * 参数delim则为分割字符串中包含的所有字符。 * 当strtok()在参数s的字符串中发现参数delim中包涵的分割字符时,则会将该字符改为\0 字符。 * 在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。 * 每次调用成功则返回指向被分割出片段的指针。 */ char *_strtok(char *strToken, const char *str) { assert(strToken != NULL); static char *last; //第二次使用strtok时,可用NULL代替strToken, //此时,作if判断,strToken == NULL, //(strToken = last) != NULL; //判断的同时,赋值:strToken = last; if (strToken == NULL && (strToken = last) == NULL) return NULL; char *s = strToken; const char *t = str; while (*s != '\0') { t = str; while (*t != '\0') { if (*s == *t) { last = s + 1; if (s - strToken == 0) { strToken = last; break; } *(strToken + (s - strToken) = '\0'; return strToken; } ++t; } ++s; } return NULL; } /*函数:memcpy *原型:void *memcpy(void *dest, const void *src, size_t n); *功能:从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 */ void *_memcpy(void *dest, const void *src, unsigned int count) { assert(dest != NULL && src != NULL); char *address = dest; while (count--) { *(char *)dest = *(char *)src; //指针后移,一直复制到大小为count时结束 dest = (char *)dest + 1; src = (char *)src + 1; } return address; } /*函数:memccpy *原型:extern void *memccpy(void *dest, void *src, unsigned char c, unsigned int count); *功能:由src所指内存区域复制不多于count个字节到dest所指内存区域,如果遇到字符c则停止复制 *返回值:如果c没有被复制,则返回NULL,否则,返回字符c 后面紧挨一个字符位置的指针 */ void *_memccpy(void *dest, const void *src, int c, unsigned int count) { assert(dest != NULL && src != NULL); while (count--) { *(char *) dest = *(char *) src; if (*(char *) src == (char)c) return ((char *)dest + 1); dest = (char *)dest + 1; src = (char *)src + 1; } return NULL; } /*函数:memchr *原型:extern void *memchr(const void *buf, int ch, size_t count); *功能:从buf所指内存区域的前count个字节查找字符ch *说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回NULL */ void *_memchr(const void *buf, int c, unsigned int count) { assert(buf != NULL); while (count--) { if (*(char *)buf == (char)c) return (void *)buf; buf = (char *)buf + 1; } return NULL; } /*函数:memcmp *原型:int memcmp(const void *buf1, const void *buf2, unsigned int count); *功能:比较内存区域buf1和buf2的前count个字节 */ int _memcmp(const void *s, const void *t, unsigned int count) { assert(s != NULL && t != NULL); while (count--) { if (*(char *)s && *(char *)t && *(char *)s == *(char *)t) } return ((char *)s - (char *)t); } /*函数:memset *原型:void *memset(void *s, int ch, size_t n); *功能:将 s 中前 n 个字节用 ch 替换并返回 s */ void *_memset(void *str, int c, unsigned int count) { assert(str != NULL); void *s = str; while (count--) { *(char *)s = (char)c; s = (char *)s + 1; } return str; } /*函数:memmove *原型:void *memmove( void* dest, const void* src,size_tcount ); *功能:由src所指内存区域复制count个字节到dest所指内存区域。 */ /* memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。 memmove的处理措施: 1.当源内存的首地址等于目标内存的首地址时,不进行任何拷贝 2.当源内存的首地址大于目标内存的首地址时,实行正向拷贝 3.当源内存的首地址小于目标内存的首地址时,实行反向拷贝 */ void *_memmove(void *dest, const void *src, unsigned int count) { assert(dest != NUll && src != NULL); char *pdest = (char *)dest; char *psrc = (char *)src; if (pdest > psrc && pdest - psrc < count) { while (count--) { *(pdest + count) = *(psrc + count); } } else { while (count--) { *pdest++ = *psrc++; } } return dest; }