目录
本章目的:
模拟实现字符串函数:strlen、strcmp、strcat、strcpy、strstr、strncmp、strncat、strncpy
介绍strtok、strerror的使用
模拟实现内存函数:memcpy、memmove、memset、memcmp
strlen模拟实现
size_t my_strlen(const char* str)
{
assert(str);
if (*str == '\0')
{
return 0;
}
return 1 + strlen(str + 1);
}
strcmp模拟实现
int my_strcmp(const char* str1,const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
strcat模拟实现
char* my_strcat(char* dest,const char* sour)
{
char* ret = dest;
assert(dest && sour);
while (*dest)
{
dest++;
}
while (*dest++ = *sour++)
{
;
}
return ret;
}
简言:
找到目标字符串的‘\0’,然后拷贝源字符串过去(包括源字符串的结束标志),返回目标字符串的起始地址。
strcpy模拟实现
char* my_strcpy(char* dest,const char* sour)
{
char* ret = dest;
assert(dest && sour);
while (*dest++=*sour++)
{
;
}
return ret;
}
strstr模拟实现
char* my_strstr(char* str,const char* substr)
{
char* cur = str;
assert(str && substr);
while (*cur)
{
char* s1 = cur;
char* s2 = (char*)substr;
while (*s1 == *s2 && *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cur;
}
cur++;
}
return NULL;
}
strncmp模拟实现
int my_strncmp(const char* str1,const char* str2,int n)
{
assert(str1 && str2);
while (*str1 == *str2 && n > 0)
{
n--;
str1++;
str2++;
}
if (n == 0)
{
return 0;
}
return *str1 - *str2;
}
strncat模拟实现
char* my_strncat(char* dest,const char* sour,int n)
{
char* ret = dest;
assert(dest && sour);
while (*dest)
{
dest++;
}
while (n--)
{
*dest++ = *sour++;
}
return ret;
}
strncpy模拟实现
char* my_strncpy(char* dest,const char* sour,int n)
{
char* ret = dest;
assert(dest && sour);
while (n--)
{
*dest++ = *sour++;
}
return ret;
}
介绍strtok
strtok函数可以某些符号达到分割字符串的效果
如你要从“[email protected]#apple”中提取“hello”、“world”、“name”、“apple”字符串,就可以使用strtok,其中“[email protected]”为目的字符串,“@.#”为分割符集合。
第一个参数strToken为要进行分割的字符串,第二个参数strDelimit为分割符的集合。
关于strtok的返回值
翻译为:所有这些函数都返回一个指针,指向在strToken中找到的下一个标记。当找不到更多令牌时,它们返回NULL。每次调用都会通过将遇到的每个分隔符替换为空字符来修改strToken。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。所以strtok函数会改变被操作的字符串,因此在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
以下是从“[email protected]#apple”分离“hello”、“world”、“name”、“apple”的代码
介绍strerror
这个函数使用起来相对简单,根据传递的错误码打印对应的错误信息,并返回字符指针。
错误码可以是0,1,2,3,4,5,6等。
如:
实际运用多数情况下与errno(一个全局变量)配套使用
errno这个全局变量会随着程序的错误自动的变动它的错误码,因此我们通常用strerror(errno)打印错误信息。
注意头文件的引用,errno的头文件是errno.h 而strerror的头文件是string.h
使用场景:
模拟实现memcpy
void* my_memcpy(void* dest, const void* sour,int num)
{
assert(dest && sour);
void* ret= dest;
while (num--)
{
*(char*)dest = *(char*)sour;
dest = (char*)dest + 1;
sour = (char*)sour + 1;
}
return ret;
}
模拟实现memmove
void* my_memcpy(void* dest, const void* sour,int num)
{
assert(dest && sour);
void ret = dest;
if (dest < sour)
{
while (num--)
{
*(char*)dest = *(char*)sour;
dest = (char*)dest + 1;
sour = (char*)sour + 1;
}
}
else
{
while (num--)
{
*((char*)dest+num) = *((char*)sour+num);
}
}
return ret;
}
相同点memmove与memcpy功能基本相同,都能进行以字节为单位拷贝内存。
不同点:memmove()能够拷贝重叠的内存、
memcpy()c标准并未要求它能完成拷贝重叠的内存。vs2019memcpy()能够拷贝重叠内存。
模拟实现memset
void* my_memset(void* dest, int c, size_t count)
{
assert(dest);
void* ret = dest;
while (count--)
{
*(char*)dest = (char)c;
dest = (char*)dest + 1;
}
return ret;
}
模拟实现memcmp
int my_memcmp(const void* str1, const void* str2,int num)
{
assert(str1 && str2);
while (*(char*)str1 == *(char*)str2 && num>0)
{
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
num--;
}
if (num == 0)
{
return 0;
}
else if (*(char*)str1 > *(char*)str2)
{
return 1;
}
else
{
return -1;
}
}
最后
如果关于本章有什么疑问,欢迎与本人交流。
如果本章出现错误的地方,欢迎指出,本人感激不尽。
如果觉得有收获的话,欢迎点赞和评论,谢谢。