string.h里主要包含了C语言对字符串操作的相关函数,这篇文章就介绍几个比较常用的
函数重新自己实现。并且每个函数给出了2种以上的不同写法,全部采用指针方式;在学习C语言过程中,重写这些字符串处理函数可以快速提升、磨练自己的指针、数组、函数相关知识,对学习是非常有帮助的;在单片机、嵌入式开发中,也会经常需要自己实现这些函数,可能有些功能系统函数不能满足的情况下,都需要自己重新实现。
字符串比较函数,用来比较两个字符串是否相等,下面给出了4种写法,其中一个是strncmp函数。
int strcmp(const char *str1, const char *str2) { const unsigned char *s1 = (const unsigned char *)str1; const unsigned char *s2 = (const unsigned char *)str2; int delta = 0; while (*s1 || *s2) { delta = *s2 - *s1; if (delta) return delta; s1++; s2++; } return 0; } int strncmp(const char *cs, const char *ct, size_t count) { unsigned char c1, c2; while (count) { c1 = *cs++; c2 = *ct++; if (c1 != c2) return c1 < c2 ? -1 : 1; if (!c1) break; count--; } return 0; } int strcmp(const char *a, const char *b) { while (*a || *b) { if (*a != *b) return 1; if (*a == 0 || *b == 0) return 1; a++; b++; } return 0; } int strcmp(const char *cs, const char *ct) { unsigned char c1, c2; int res = 0; do { c1 = *cs++; c2 = *ct++; res = c1 - c2; if (res) break; } while (c1); return res; }
strlen是计算字符串长度的函数,比较常用,代码也最简单,下面写了两种实现方法。
size_t strlen(const char *s) { const char *sc = s; while (*sc != '\0') sc++; return sc - s; } size_t strlen(const char *s) { const char *sc; for (sc = s; *sc != '\0'; ++sc) return sc - s; } size_t strnlen(const char *s, size_t count) { const char *sc; for (sc = s; count-- && *sc != '\0'; ++sc) return sc - s; }
strstr字符串查找函数,用来查找指定的字符串在源字符串里是否存在,存在就返回地址。
这个就给出了一种写法。
char *strstr(const char *s1, const char *s2) { size_t l1, l2; l2 = strlen(s2); if (!l2) return (char *)s1; l1 = strlen(s1); while (l1 >= l2) { l1--; if (!memcmp(s1, s2, l2)) return (char *)s1; s1++; } return NULL; }
memcmp内存比较函数,用来比较两个内存地址里的数据是否相等,不局限于字符串,只要是合法内存都可以按字节比较。
int memcmp(const void *cs, const void *ct, size_t count) { const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; int res = 0; while (su1 < end) { res = *su1++ - *su2++; if (res) break; } return res; } int memcmp(const void *cs, const void *ct, size_t count) { const unsigned char *su1, *su2; int res = 0; for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) if ((res = *su1 - *su2) != 0) break; return res; }
strcpy字符串拷贝函数,用来将目标字符串拷贝到指定的地址中。目标字符串必须是‘\0’结束。 这里写了2种函数,一个strcpy、一个strncpy。
char *strcpy(char *dest, const char *src) { char *tmp = dest; while ((*dest++ = *src++) != '\0') return tmp; } char *strncpy(char *dest, const char *src, size_t count) { char *tmp = dest; while (count) { if ((*tmp = *src) != 0) src++; tmp++; count--; } return dest; } size_t strlcpy(char *dest, const char *src, size_t size) { size_t ret = strlen(src); if (size) { size_t len = (ret >= size) ? size - 1 : ret; memcpy(dest, src, len); dest[len] = '\0'; } return ret; }
内存拷贝函数,将目标内存数据拷贝导致指定内存位置,不局限于字符串。
void *memcpy(void *__dest, __const void *__src, size_t __n) { int i = 0; unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; for (i = __n >> 3; i > 0; i--) { *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; } if (__n & 1 << 2) { *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; } if (__n & 1 << 1) { *d++ = *s++; *d++ = *s++; } if (__n & 1) *d++ = *s++; return __dest; } void *memcpy(void *__dest, __const void *__src, size_t __n) { int i; char *d = (char *)__dest, *s = (char *)__src; for (i = 0; i < __n; i++) d[i] = s[i]; return __dest; } static inline void *memcpy(void *__dest, const void *__src, size_t __n) { int i; const char *s = __src; char *d = __dest; for (i = 0; i < __n; i++) d[i] = s[i]; return __dest; }