字符串函数
strlen
获取字符串的长度:传入的字符串指针开始,逐个检查字符,直到遇到字符串末尾的空字符 \0
模拟实现
// 1.指针-指针
int my_strlen(char *s)
{
assert(str); // 验证程序中字符串是否存在,如果不存在,程序停止执行
char *p = s;
while(*p != '\0' )
p++;
return p-s; // s为传入字符的起始位置
}
// 2.计数器
int my_strlen(const char*str)
{
assert(str)
int count = 0;
while(*str)
{
count++:
str++'
}
return count;
}
// 3.不创建临时变量的计数器
int my_strlen(const char*str)
{
assert(str)
if(*str == '\0')
return 0;
else
return 1 + my_strlen(str + 1); // 递归调用自身函数,计算字符串长度
}
strcpy
将src字符串内容复制到dest中去,dest必须具有足够的空间来容纳复制过来的字符串,否则可能会导致缓冲区溢出。另外,dest和src不能指向同一个字符串,否则会导致未定义的行为。
char *my_strcpy(char *dest,con char *src)
{
char *ret = dest; // 备份
assert(dest != NULL):
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
strncpy
函数将源字符串的内容复制到目标字符串中,但最多只复制n个字符,如果源字符串的长度小于n,则会在目标字符串中填充剩余的空间,如果源字符串的长度大于或等于n,则目标字符串不会以空字符\0结尾。
char *my_strncpy(char *dest,const char *src, int n)
{
chat *tmp = dest;
assert(dest != NULL);
assert(scr != NULL):
while (n && (*dest++ = *src++))
{
n--;
}
if (n > 0)
{
while (--n)
{
*dest++ = '\0'; // 填充剩余的空间
}
}
return dest;
}
strcat
用于将一个字符串追加到另一个字符串的末尾
char *my_strcat(char *dest,const char* src)
{
char*tmp = dest; // 备份;
assert(dest != NULL);
assert(src != NULL);
while(dest)
{
*dest++;
}
while((*dest++ = *src++))
{
;
}
return dest;
}
strncat
将源字符串的前若干个字符拼接到目标字符串的末尾
char *my_strcat(char *dest,const char* src,size_t n)
{
char*tmp = dest; // 备份;
assert(dest != NULL);
assert(src != NULL);
while(dest)
{
*dest++;
}
while((*src!='\0')&&n-->0)
{ // 直到遇到源字符串的结尾或者拷贝了 n 个字符
*dest++ = *src++;
}
return tmp;
}
strcmp
比较两个字符串。逐个比较两个字符串中对应位置的字符,并返回它们的差值,或者返回 0,表示两个字符串相等,判断的是对应ASCII码值的大小
int *my_strcmp(const char*str1,const char *str2)
{
assert(*str1 != NULL);
assert(*str2 != NULL);
while(*str1 == *str2)
{
if(*str1 = '\0');
return 0;
str1++;
str2++:
}
return *str1 - *str2;
}
strncmp
可以指定比较的字符数目
int strncmp(const char *str1;const char *str2;size_t n)
{
assert(str1 ! == NULL);
assert(str2 ! == NULL);
while(n-- >0 && *str1 == *str2)
{ // n-- > 0 先比较n是否>0;如果满足条件则执行n--
str1++;
str2++;
)
if(n == 0 || (str1 == '\0' && str2 == '\0'));
{
return 0;
} else {
return *str1 - *str2;
}
}
strstr
在一个字符串中查找指定子字符串的第一次出现位置
strstr(const char *str1,const char *str2)
{
if(str2 == '\0';
return (*char)str1;
while(*str1 != '\0')
{
const *p1 = *str1;
const *p2 = *str2;
while(*p1 != '\0' && *p2 != '\0' && *p1 = *p2)
{
p1++;
p2++;
}
if(*p2 == '\0')
{
return (*char)str1;// 如果子字符串的所有字符都匹配,则返回当前位置的指针
}
str1++; // 继续查找
}
return NULL;
}
strtok
分割字符串
声明:char *strtok(char *str, const char *delim)
- str -- 要被分解成一组小字符串的字符串
- delim -- 包含分隔符的 C 字符串
例子
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.bilibili.com - website";
const char s[2] = "-";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
效果
This is
www.bilibili.com
website
srerror
内存函数
memcpy
将一个内存区域的内容复制到另一个内存区域
// memcpy函数拷贝结束后,会返回目标空间的起始地址
void* my_memcpy(void* dest, void* src, size_t num)
{
void* ret = dest;
int i = 0;
assert(dest && src);
while (num--)
{
*(char*)dest = *(char*)src;
src = (char*)src + 1;
dest = (char*)dest + 1;
}
return ret;
}
mememove
用于在内存中移动一块数据。其功能类似于memcpy,但它能够处理源地址和目标地址重叠的情况
memmove函数拷贝完成后,会返回目标空间的起始地址
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
//前->后
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//后->前
while (num--)
{
*((char*)dest+num) = *((char*)src + num);
}
}
return ret;
}
memset
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
输出:xxxxxxworld
memcmp
int memcmp(const void *ptr1, const void *ptr2, size_t num);
参数说明:
ptr1指向要比较的第一个内存区域的指针。
ptr2指向要比较的第二个内存区域的指针。
num要比较的字节数。
函数返回值:
返回值为 0 表示两个内存区域的内容相同。
返回值小于 0 表示第一个内存区域小于第二个内存区域。
返回值大于 0 表示第一个内存区域大于第二个内存区域。