strlen函数
//循环方式
size_t strlen(const char *string)
{
assert(string != nullptr);
int count = 0;
while (*(string++))
{
count++;
}
return count;
}
//递归方式
size_t strlen(const char* string)
{
assert(string != nullptr);
if (*string == '\0')
return 0;
return 1 + strlen(++string);
}
strcpy函数
char* strcpy(char* dest, const char* src)
{
//保证两个指针都不能为空
assert(dest != nullptr&&src != nullptr);
char* ret = dest;
while (*dest++ = *src++);
return ret;
}
strcat
char* strcat(char* dest, const char* src)
{
assert(dest != nullptr&&src != nullptr);
char* ret = dest;
while (*dest)
{
dest++;
}
while (*dest++ = *src++);
return ret;
}
strstr:字符串匹配函数
char* strstr(const char* string, const char*str)
{
assert(string != nullptr&&str != nullptr);
const char* start_str = str;
while (*string)
{
while (*string != *str)
{
++string;
}
const char* start = string;
while (*string == *str)
{
++string;
++str;
if (*str == '\0')
return (char*)start;
}
str = start_str;
string = start + 1;
}
return nullptr;
}
char* strstr(const char* string, const char*str)
{
assert(string != nullptr&&str != nullptr);
const char* start_str = str;
while (*string)
{
const char* tmp = string;
while (*string&&*str && (*string == *str))
{
++string;
++str;
}
if (*str == '\0')
{
return (char*)tmp;
}
str = start_str;
++string;
}
return nullptr;
}
strcmp:字符串比较函数
int strcmp(const char* str1, const char* str2)
{
assert(str1 != nullptr&&str2 != nullptr);
while (*str1 == *str2)
{
if (str1 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
return -1;
}
memcpy和memmove:字符串拷贝函数
memcpy:不要用于内存重叠的拷贝
而memmove:可以
实际中,有些库,使用memcpy也可以拷贝内存重叠的字符串,
void* memcpy(void* dest, const void* src, size_t count)
{
assert(dest != nullptr&&src != nullptr);
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
void* memmove(void* dest, const void* src, size_t count)
{
assert(dest != nullptr&&src != nullptr);
void* ret = dest;
if ((char*)src + count<(char*)dest + count && (char*)src + count>(char*)dest)
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
else
{
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
return ret;
}
atoi和itoa函数
//将一个数字字符串转换为int类型
int atoi(const char* string)
{
assert(string != nullptr);
int sign = 1; //符号位
int num = 0; //数字
//int isspace( int c );如果该字符是一个空格,则返回非0的数
//*string 解引用string字符串 (unsigned char)*string 取string字符串的第一个字符
// int)(unsigned char)*string 此时再强转为int的原因是因为isspace 的参数是一个int乐行
while (isspace((int)(unsigned char)*string))
{
++string;
}
if (*string == '-')
{
sign = -1;
}
if (*string == '-' || *string == '+')
{
string++;
}
while (*string >= '0'&&*string <= '9')
{
num = num * 10 + *string - '0' + 0;
string++;
}
return sign*num;
}
//value :要转换的数字 string:转换好的字符串 radix:要转换的进制 只支持2~36进制
//将一个int类型的数字转换为对应进制的字符串
char* itoa(int value, char* string, int radix)
{
assert(radix >= 2 && radix <= 36);
//数组33位就已经足够了,因为int类型为32位,如果转换为10进制,需要有一个符号位
char tmp[33];
char* tp = tmp;
int i;
unsigned int v;
int sign;
char* sp;
//如果要转换成十进制数字,需要判断符号,以此确定是正数还是负数
sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned int)value;
//如果第一次判断v为0;可以通过tp==tmp进入
while (v || tp == tmp)
{
i = v%radix;
v = v / radix;
if (i < 10)
*tp++ = '0' + i;
else
*tp++ = 'a' + (i - 10);
}
if (string == 0)
string = (char*)malloc(tp - tmp + 1 + sign);
sp = string;
if (sign)
*sp++ = '-';
while (tp>tmp)
*sp++ = *--tp;
*sp = '\0';
sp = nullptr;
return string;
}