模拟实现C语言库函数
str库函数
\#include <stdio.h>
\#include <stdlib.h>
\#include <assert.h>
1.模拟实现strcpy
将源字符串src拷贝赋值到目标字符串dest中
char *my_strcpy(char *dest, const char* src)
{
assert(dest);
assert(src);
char *ret = dest;
while (*dest++ = *src++)
;
return ret;
}
2.模拟实现strlen
从字符串起始位置开始到\0
结束,结果不包括\0
的长度
一、计数法
int my_strlen(const char* str)
{
assert(str);
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
二、指针相减法
int my_strlen2(const char* str)
{
assert(str);
const char*ptr = str;
while (*str)
{
str++;
}
return str - ptr;
}
三、递归法
int my_strlen3(const char* str)
{
assert(str);
if (*str)
{
return 1 + my_strlen3(str+1);
}
return 0;
}
3.模拟实现strcat
字符串追加函数,先让目标字符串指针指到字符串末尾,然后加上源字符串
char* my_strcat(char* dest, const char* src)
{
assert(dest);
assert(src);
char* ptr = dest;
while (*dest)
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return ptr;
}
4.模拟实现strcmp
比较每一位字符的ASCII码值,返回值为0说明相等
int my_strcmp(char* dest, const char* src)
{
assert(dest);
assert(src);
while ((*dest == *src) && (*dest != '\0'))
{
dest++;
src++;
}
return *dest - *src; //返回相应字符ASCII码之差
}
5.模拟实现strstr
在str1中查找str2,找到了返回第一次出现的位置
char *my_strstr(const char* str1, const char* str2)
{
assert(str1);
assert(str2);
if (*str2 == '\0')
{
return (char*)str1;
}
while (*str1 != '\0')
{
const char* p1 = str1;
const char* p2 = str2;
while ((*p2 != '\0') && (*p1 == *p2))
{
p1++;
p2++;
if (*p2 == '\0')
{
return (char*)str1;
}
}
str1++;
}
return NULL;
}
6.模拟实现strchr
在str中查找字符ch第一次出现的位置,返回字符位置指针
char* my_strchr(const char* str, char ch)
{
assert(str);
while (*str != '\0')
{
if (*str == ch)
{
return (char*)str;
}
str++;
}
return NULL;
}
7.模拟实现strrchr
/在字符串str中查找字符ch最后一次出现的位置,返回字符位置指针
一、从前往后找
char *my_strrchr(const char* str, char ch)
{
assert(str);
char* pos = 0; //记录位置的指针变量
while (*str != '\0')
{
if (*str == ch)
{
pos = str;
str++;
}
else
{
str++;
}
}
if (pos == 0)
return NULL;
else
return pos;
}
二、从后往前找
char* my_strrchr2(const char* str, char ch, int len)
{
assert(str);
str = str + len - 1;
while (*str != '\0')
{
if (*str == ch)
{
return str;
}
str--;
}
return NULL;
}
8.模拟实现strncpy
从源字符串src中拷贝n个字符赋值到目标字符串dest中
char* my_strncpy(char* dest, const char*src, int n)
{
assert(dest);
assert(src);
char* ret = dest;
while (n)
{
*dest++ = *src++;
if ('\0' == *src)
{
dest++;
}
n--;
}
return ret;
}
9.模拟实现strncat
先让目标字符串指针指到字符串末尾,然后加上源字符串中的n个字符
char* my_strncat(char* dest, const char* src, int n)
{
assert(dest);
assert(src);
char* ret = dest;
while (*dest != '\0')
{
dest++;
}
while (n)
{
*dest++ = *src++;
if (*src == '\0')
{
break;
}
n--;
}
return ret;
}
10.模拟实现strncmp
比较两个字符串中的n个字符的ASCII码
char* my_strncmp(const char* dest, const char* src, int n)
{
assert(dest);
assert(src);
while (n && (*dest++ == *src++))
{
if (*src == '\0')
{
return 0;
}
n--;
}
if (n == 0)
{
return 0;
}
if (*dest > *src)
{
return 1;
}
else
return -1;
}
11.模拟实现strlwr、strupr
转化字符大小写
char* my_strlwr(char* src) //将字符全部转化为小写
{
assert(src);
char *ret = src;
while (*src != '\0')
{
if (*src >= 'A' && *src <= 'Z')
{
*src += 0x20;
}
src++;
}
return ret;
}
char* my_strupr(char* src) //将字符全部转化为大写
{
assert(src);
char*ret = src;
while (*ret != '\0')
{
if (*ret >= 'a' && *ret <= 'z')
{
*ret = *ret - 32;
}
ret++;
}
return src;
}
内存操作函数
1.模拟实现memcpy
src和dest是指向内存中的两块空间,从内存中的src位置开始复制num个字节到dest位置,返回指向dest的指针,可能会存在内存重叠问题
void *my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest);
assert(src);
void* ret = dest;
char* pdest = (char*)dest;
char* psrc = (char*)src;
while (num--)
{
*pdest++ = *psrc++;
}
return ret;
}
2.模拟实现memmove
可以有效的解决内存重叠,只要二者之间的内存空间间隔在num个字节之外
void* my_memmove(void *dest, const void *src, size_t num)
{
assert(dest);
assert(src);
void* ret = dest;
char* pdest = (char*)dest;
char* psrc = (char*)src;
if (pdest <= psrc && pdest >= psrc + num) //正常情况下从前往后拷贝
{
while (num--)
{
*pdest++ = *psrc++;
}
}
else
{
while (num--)
{
*(pdest + num) = *(psrc + num); //出现内存覆盖时从后往前拷贝
}
}
return ret;
}
模拟实现atoi函数
atoi函数是将字符串转化为整型,函数原型是:
int atoi(const char * str);
在实现这个函数时,应该考虑以下问题:
1.空字符串
2.前面有空格
3.正负号
4.异常字符
5.输出数据溢出问题
enum State{
NORMAL,
ABNORMAL
}state;
state = ABNORMAL; //初始化为异常状态
int my_atoi(const char* str)
{
assert(str);
int flag = 1; //记录为正
long long ret = 0;
while (*str == ' ') //跳过空格字符
{
str++;
}
if ((*str == '+') || (*str == '-')) //判断正负号
{
if (*str == '+')
{
str++;
}
else
{
flag = -1;
str++;
}
}
if (*str == '\0')
{
return 0;
}
while (*str != '\0')
{
if ((*str >= '0') && (*str <= '9'))
{
ret = ret * 10 + flag*(*str - '0');
if ((ret > INT_MAX) || (ret < INT_MIN))
{
ret = 0;
break;
}
}
else //如果是异常字符,直接返回
break;
str++;
}
if (*str == '\0')
{
state = NORMAL; //走完了 说明字符串无异常
}
return (int)ret;
}
测试代码
int main()
{
//char arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
//char arr2[10] = { 1,2,3,4,5,7,4 };
//int i = 0;
////my_memcpy(arr1, arr2, 10);
//my_memmove(arr1, arr2, 10);
//for (i = 0; i < 10; i++)
//{
// printf("%d ", arr1[i]);
//}
char* arr[10] = { 0 };
char* p = "-1234";
char* q = " 345";
char* r = "67rg";
char* c = "abcdef";
char* s = "";
char* t = NULL;
char* u = "2200000000";
char* v = "-2000000000";
int tmp = my_atoi(c);
printf("%d\n", tmp);
system("pause");
return 0;
}
//int main()
//{
// char arr1[20] = "ADFGBDabcd";
// char arr2[10] = "qwer";
// char *p = "qwerqasddggfh";
// char *q = "qwer ";
// char *s = "Hello World!";
//
// //char* ch = my_strcpy(arr, p);
// //int ret = my_strlen3(p);
// //char* str = my_strcat(arr, p);
// /*int ret = my_strncmp(p, q, 5);
// if (ret == 0)
// printf("p等于q\n");
// else if (ret < 0)
// printf("p小于q\n");
// else{
// printf("p大于q\n");
// }*/
//
// char* str3 = my_strlwr(arr1);
// printf("%s\n", str3);
//
//
// /*char* str4 = my_strupr(arr1);
// printf("%s\n", str4);*/
//
//
// /*char* str = my_strncpy(arr1, arr2, 4);
// printf("%s\n", str);*/
//
// //char* str1 = my_strncat(arr1, arr2, 4);
// //printf("%s\n", str1);
// //char *ch = my_strchr(p, 'a');
// //printf("%s\n", ch);
//
// //char *chend = my_strrchr(p, 'd');
// //printf("%s\n", chend);
//
// //char *chend2 = my_strrchr(p, 'd', my_strlen(p));
// //printf("%s\n", chend);
// char* ret = my_strstr(p, q);
// //printf("%s\n", ret);
//
// //printf("%s\n", ch);
// //printf("%d\n", ret);
// //printf("%s\n", str);
// system("pause");
// return 0;
//}