C语言str系列库函数在不同的库中有不同的实现方法,但原理都是一样的。因为库函数都是没有进行入口参数检查的,并且str系列库函数在面试中经常容易被面试官喊在纸上写某一个函数的实现,因此本文参考了OpenBSD和vc++ 8.0库中的代码,结合自己的编程习惯,部分整理如下:
1、strcpy
- char * strcpy(char *dst, const char *src)
- {
- char *d;
- if (dst == NULL || src == NULL)
- return dst;
- d = dst;
- while (*d++ = *src++) // while ((*d++ = *src++) != '\0')
- ;
- return dst;
- }
2、strncpy
- //copy at most n characters of src to dst
- //Pad with '\0' if src fewer than n characters
- char *strncpy(char *dst, const char*src, size_t n)
- {
- char *d;
- if (dst == NULL || src == NULL)
- return dst;
- d = dst;
- while (n != 0 && (*d++ = *src++)) /* copy string */
- n--;
- if (n != 0)
- while (--n != 0)
- *d++ == '\0'; /* pad out with zeroes */
- return dst;
- }
注意 n是unsigned int,在进行n--操作时特别要小心。如果不小心写成下面这样就会出错:
- while (n-- != 0 && (*d++ = *src++))
- ;
- while (n-- != 0)
- *d++ = '\0';
3、strcat
- char *strcat(char *dst, const char *src)
- {
- char *d;
- if (dst == NULL || src == NULL)
- return dst;
- d = dst;
- while (*d)
- d++;
- //while (*d++ != 0);
- //d--;
- while (*d++ = *src++)
- ;
- return dst;
- }
4、strncat
写法1:
- //concatenate at most n characters of src to the end of dst
- //terminates dst with '\0'
- char *strncat(char *dst, const char *src, size_t n)
- {
- if (NULL == dst || NULL == src)
- return dst;
- if (n != 0)
- {
- char *d = dst;
- do
- {
- if ((*d = *src++) == '\0' )
- return dst; //break
- d++;
- } while (--n != 0);
- *d = '\0';
- }
- return dst;
- }
- char *strncat(char *dst, const char *src, size_t n)
- {
- char *d;
- if (dst == NULL || src == NULL)
- return dst;
- d = dst;
- while (*d)
- d++;
- //(1)
- while (n != 0)
- {
- if ((*d++ = *src++) == '\0')
- return dst;
- n--;
- }
- //(2)
- //while (n--) //这种方式写最后n的值不为0,不过这个n后面不会再被使用
- // if ((*d++ == *src++) == '\0')
- // return dst;
- *d = '\0';
- return dst;
- }
5、strcmp
- int strcmp(const char *s1, const char *s2)
- {
- if (s1 == NULL || s2 == NULL)
- return 0;
- //(1)
- //while (*s1 == *s2++)
- // if (*s1++ == '\0')
- // return 0;
- //(2)
- for (; *s1 == *s2; s1++, s2++)
- if (*s1 == '\0')
- return 0;
- return *(unsigned char*)s1 - *(unsigned char*)s2;
- }
6、strncmp
- int strncmp(const char *s1, const char *s2, size_t n)
- {
- if (s1 == NULL || s2 == NULL)
- return 0;
- if (n == 0)
- return 0;
- do
- {
- if (*s1 != *s2++)
- return *(unsigned char*)s1 - *(unsigned char*)--s2;
- if (*s1++ == '\0')
- break;
- } while (--n != 0);
- //do
- //{
- // if (*s1 != *s2)
- // return *(unsigned char*)s1 - *(unsigned char*)s2;
- // if (*s1 == '\0')
- // break;
- // s1++;
- // s2++;
- //} while (--n != 0);
- return 0;
- }
7、strstr
写法1:
- //return pointer to first occurrence of find in s
- //or NULL if not present
- char *strstr(const char *s, const char *find)
- {
- char *cp = (char*)s;
- char *s1, *s2;
- if (s == NULL || find == NULL)
- return NULL;
- while (*cp != '\0')
- {
- s1 = cp;
- s2 = (char*)find;
- while (*s1 && *s2 && *s1 == *s2)
- s1++, s2++;
- if(*s2 == '\0')
- return cp;
- cp++;
- }
- return NULL;
- }
写法2:参照简单模式匹配算法
- char *strstr(const char *s, const char *find)
- {
- int i = 0, j = 0;
- while (*(s + i) != '\0' && *(find + j) != '\0')
- {
- if (*(s + i + j) == *(find + j))
- j++; //继续比较后一字符
- else
- {
- i++; //开始新一轮比较
- j = 0;
- }
- }
- return *(find + j) == '\0' ? (char*)(s + i) : NULL;
- }
8、strchr
- //return pointer to first occurrence of ch in str
- //NULL if not present
- char *strchr(const char*str, int ch)
- {
- while (*str != '\0' && *str != (char)ch)
- str++;
- if(*str == (char)ch)
- return (char*)str;
- return NULL;
- }
9、strrchr
- //return pointer to last occurrence of ch in str
- //NULL if not present
- char *strrchr(const char *str, int ch)
- {
- if (str == NULL)
- return NULL;
- char *s = (char*)str;
- while (*s++)
- ; /* find end of string */
- while (--s != str && *s != (char)ch)
- ; /* search towards front */
- if(*s == (char)ch)
- return (char*)s;
- return NULL;
- }
10、strlen
- size_t strlen(const char *str)
- {
- if (str == NULL)
- return 0;
- const char *eos = str;
- while (*eos++)
- ;
- return (eos - 1 - str);
- }
C语言str系列库函数之strtok(): http://blog.csdn.net/u013071074/article/details/27716097
C语言str系列库函数之strspn()、strcspn()和strpbrk():
http://blog.csdn.net/u013071074/article/details/27808497
str系列库函数的使用实例:
http://www.cplusplus.com/reference/cstring/