发布时间:2023-09-20 09:00
看到很多面试都会要求你写一些简单的字符串操作函数,这些函数看起来挺简单的,但是自己写的时候就会发现不少的问题。所以我自己把大部分的字符串操作函数都写了一遍,然后用了个测试程序来测试自己写的函数与库函数是否相同。包括字符串长度函数、不受限制的字符串函数、受限制的字符串函数、字符串查找基础函数。下面直接上代码:
my_string.h 字符串操作函数头文件
#include
#define NUL '\0'
#ifndef _MY_STRING_H_H
#define _MY_STRING_H_H
//字符串长度
size_t my_strlen(char const *dst);
//不受限制的字符串函数
char *my_strcpy(char *dst, char const *src);
char *my_strcat(char *dst, char const *src);
int my_strcmp(char const *dst, char const *src);
//受限制的字符串函数
char *my_strncpy(char *dst, char const *src, size_t len);
char *my_strncat(char *dst, char const *src, size_t len);
int my_strncmp(char const *dst, char const *src, size_t len);
//字符串查找基础
char *my_strchr(char const *str, int ch);
char *my_strpbrk(char const *str, char const *group);
char *my_strstr(char const *s1, char const *s2);
char *my_strrchr(char const *str, int ch);
char *my_strrpbrk(char const *str, char const *group);
char *my_strrstr(char const *s1, char const *s2);
#endifmy_string.cpp
字符串操作函数源文件
#include "my_string.h"
//字符串长度
size_t my_strlen(char const *dst)
{
size_t length = 0;
while (*dst++ != NUL)
length++;
return length;
}
//不受限制的字符串函数
char *my_strcpy(char *dst, char const *src)
{
char *p = dst;
while (*src != NUL)
*dst++ = *src++;
*dst = NUL;
return p;
}
char *my_strcat(char *dst, char const *src)
{
char *p = dst;
while (*dst++ != NUL);
dst--;
while (*src != NUL)
*dst++ = *src++;
*dst = NUL;
return p;
}
int my_strcmp(char const *dst, char const *src)
{
while (*dst != NUL && *src != NUL)
{
if (*dst != *src)
{
if (*dst > *src)
return 1;
else
return -1;
}
dst++;
src++;
}
if (*dst == NUL && *src == NUL)
return 0;
else if (*dst == NUL && *src != NULL)
return -1;
else
return 1;
}
//受限制的字符串函数
char *my_strncpy(char *dst, char const *src, size_t len)
{
char *p = dst;
while (len != 0)
{
if (*src != NUL)
*dst++ = *src++;
else
*dst++ = NUL;
len--;
}
return p;
}
char *my_strncat(char *dst, char const *src, size_t len)
{
char *p = dst;
while (*dst++ != NUL);
dst--;
while (len != 0)
{
if (*src == NUL)
break;
*dst++ = *src++;
len--;
}
*dst = NUL;
return p;
}
int my_strncmp(char const *dst, char const *src, size_t len)
{
while (len != 0)
{
if (*dst == NUL || *src == NUL)
break;
if (*dst != *src)
{
if (*dst > *src)
return 1;
else
return -1;
}
dst++;
src++;
len--;
}
if (len == 0 || *dst == *src)
return 0;
else if (*dst == NUL && *src != NUL)
return -1;
else
return 1;
}
//字符串查找基础
char *my_strchr(char const *str, int ch)
{
while (*str != NUL)
{
if (ch == *str)
break;
str++;
}
if (*str == NUL)
return NULL;
return (char *)str;
}
char *my_strpbrk(char const *str, char const *group)
{
char *p = NULL;
while (*group++ != NUL)
{
p = my_strchr(str, *group);
if (p != NULL)
break;
}
return p;
}
char *my_strstr(char const *s1, char const *s2)
{
char *p;
if (*s2 != NUL)
{
while (*s1 != NUL)
{
if (*s2 == *s1)
{
p = (char *)s1;
while (*s2 != NUL)
{
if (*s1 != *s2)
break;
s1++;
s2++;
}
if (*s2 == NUL)
return p;
s1 = p;
}
s1++;
}
return NULL;
}
return (char *)s1;
}
char *my_strrchr(char const *str, int ch)
{
char *last = NULL, *current = NULL;
current = my_strchr(str, ch);
while (current != NULL)
{
last = current;
current = my_strchr(last + 1, ch);
}
return last;
}
char *my_strrstr(char const *s1, char const *s2)
{
char *last = NULL, *current = NULL;
if (*s2 != NUL)
{
current = my_strstr(s1, s2);
while (current != NULL)
{
last = current;
current = my_strstr(last + 1, s2);
}
}
return last;
}
char *my_strrpbrk(char const *str, char const *group)
{
char *last = NULL, *current = NULL;
if (*group != NUL)
{
current = my_strpbrk(str, group);
while (current != NULL)
{
last = current;
current = my_strpbrk(last + 1, group);
}
}
return last;
}main.cpp
测试程序,主要是为了测试自己的函数与库函数结果是否一致
#include
#include
#include "my_string.h"
//主函数
int main(void)
{
int len;
char str_cpy1[13] = "abcdefghijkl", str_cpy2[13] = "abcdefghijkl";
char str_ncpy1[13] = "abcdefghijkl", str_ncpy2[13] = "abcdefghijkl";
char str_cat1[13] = "hello", str_cat2[13] = "hello";
char str_ncat1[13] = "hello", str_ncat2[13] = "hello";
char *pstr;
char const *pcstr;
printf("********字符串长度********\n");
len = my_strlen("test");
printf("my_strlen = %d\n", len);
len = strlen("test");
printf("strlen = %d\n", len);
printf("\n********不受限制的字符串函数********\n");
pstr = my_strcpy(str_cpy1, "hello world!");
printf("my_strcpy = %s\n", pstr);
pstr = strcpy(str_cpy2, "hello world!");
printf("strcpy = %s\n", pstr);
pstr = my_strcat(str_cat1, " world!");
printf("my_strcat = %s\n", pstr);
pstr = strcat(str_cat2, " world!");
printf("strcat = %s\n", pstr);
len = my_strcmp("test", "testa");
printf("my_strcmp = %d\n", len);
len = strcmp("test", "testa");
printf("strcmp = %d\n", len);
printf("\n********长度受限制的字符串函数********\n");
pstr = my_strncpy(str_ncpy1, "hello wor", 9);
printf("my_strncpy = %s\n", pstr);
pstr = strncpy(str_ncpy2, "hello wor", 9);
printf("strncpy = %s\n", pstr);
pstr = my_strncat(str_ncat1, " world!", 10);
printf("my_strncat = %s\n", pstr);
pstr = strncat(str_ncat2, " world", 10);
printf("strncat = %s\n", pstr);
len = my_strncmp("test", "testa", 5);
printf("my_strncmp = %d\n", len);
len = strncmp("test", "testa", 5);
printf("strncmp = %d\n", len);
printf("\n********字符串查找基础********\n");
pstr = my_strchr("hello world!", ' ');
printf("my_strchr = %s\n", pstr);
pcstr = strchr("hello world!", 'h');
printf("strchr = %s\n", pcstr);
pstr = my_strpbrk("hello world!", "abcd");
printf("my_strpbrk = %s\n", pstr);
pcstr = strpbrk("hello world!", "abcd");
printf("strpbrk = %s\n", pcstr);
pstr = my_strstr("hello world!", "!");
printf("my_strstr = %s\n", pstr);
pcstr = strstr("hello world!", "!");
printf("strstr = %s\n", pcstr);
pstr = my_strrchr("hello world!", 'a');
printf("my_strrchr = %s\n", pstr);
pcstr = strrchr("hello world!", 'a');
printf("strrchr = %s\n", pcstr);
pstr = my_strrstr("hello world!", "!");
printf("my_strrstr = %s\n", pstr);
pstr = my_strrpbrk("hello world!", "abcd");
printf("my_strrpbrk = %s\n", pstr);
return 0;
} 自己现在写的函数只是为了实现和库函数相同的功能,不是要改进库函数的一些缺点,更多的是为了锻炼一下自己的基础功底。下面说明一下我在实现函数功能时注意的问题:
(1)strlen函数处理的是一个真正的字符串(以NUL结尾的字符串),找到NUL时结束,所以如果一个字符串没有以NUL结束的话,函数就会一直到内存中找到结束标志为止。
(2)strcpy和strcat函数在使用时,要考虑目标字符数组要能容纳所要承载的字符串。strcmp函数的返回值要注意,标准没有规定用于提示不相等的具体值。如果第1个字符串大于第2个字符串就返回一个大于0的值,如果第1个字符串小于第2个字符串就返回一个小于0的值,两个字符串相等时就返回0(这里我只用1、-1和0代替了一下)。
(3)strncpy函数,如果源字符串的长度小于len(待复制字符数),不够的用NUL补齐,如果源字符串的长度大于等于len,只复制len个。strncat与strncpy有几点不同,1.最多复制len个字符到目标字符数组后面。而且在结果字符串后面添加一个NUL字符; 2.不会像strlen一样对目标数组用NUL进行填充。
下面是我的测试结果图: