C/C++总述:Study C/C++-CSDN博客
目录
求字符串长度strlen长度不受限制的字符串函数strcpystrcatstrcmp长度受限制的字符串函数介绍strncpystrncatstrncmp字符串查找strstrstrtok内存操作函数memcpymemmove
一、strlen
描述
C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
声明
下面是 strlen() 函数的声明。
size_t strlen(const char *str)
参数
- str -- 要计算长度的字符串。
返回值
该函数返回字符串的长度。
模拟实现
size_t my_strlen(const char* str)
{
const char* start = str; //字符串的起始位置就是str
const char* end = str;
while (*end != '\0') //用来找到字符串的末尾处
{
end++;
}
return end - start; //最后指针减指针得到了字符串的长度
}
二、strcpy
描述
C 库函数 char *strcpy(char *dest, const char *src) 把 src 所指向的字符串复制到 dest。
需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。(会将源字符串中的 '\0' 拷贝到目标空间).
声明
下面是 strcpy() 函数的声明。
char *strcpy(char *dest, const char *src)
参数
- dest -- 指向用于存储复制内容的目标数组。
- src -- 要复制的字符串。
返回值
该函数返回一个指向最终的目标字符串 dest 的指针。
模拟实现
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
三、strcat
描述
C 库函数 char *strcat(char *dest, const char *src) 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
声明
下面是 strcat() 函数的声明。
char *strcat(char *dest, const char *src)
参数
- dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
- src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。
返回值
该函数返回一个指向最终的目标字符串 dest 的指针。
模拟实现
char *my_strcat(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while(*dest)
{
dest++;
}
while((*dest++ = *src++))
{
;
}
return ret;
}
四、strcmp
描述
C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较。
声明
下面是 strcmp() 函数的声明。
int strcmp(const char *str1, const char *str2)
参数
- str1 -- 要进行比较的第一个字符串。
- str2 -- 要进行比较的第二个字符串。
返回值
该函数返回值如下:
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
模拟实现
int my_strcmp(const char *str1, const char *str2)
{
while (*str1 && (*str1 == *str2))
{
str1++;
str2++;
}
return *(unsigned char*)str1 - *(unsigned char*)str2;
}
五、 strstr
描述
C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
声明
下面是 strstr() 函数的声明。
char *strstr(const char *haystack, const char *needle)
参数
- haystack -- 要被检索的 C 字符串。
- needle -- 在 haystack 字符串内要搜索的小字符串。
返回值
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。
模拟实现
int my_strstr(const char* haystack, const char* needle)
{
if (!*needle)
{
return 0;
}
if (!*haystack || strlen(needle) > strlen(haystack))
{
return -1;
}
int i, j;
for (i = 0; i <= strlen(haystack) - strlen(needle); i++)
{
for (j = 0; j < strlen(needle); j++)
{
if (haystack[i+j] != needle[j])
{
break;
}
}
if (j == strlen(needle))
{
return i;
}
}
return -1;
}
六、strtok
描述
C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
声明
下面是 strtok() 函数的声明。
char *strtok(char *str, const char *delim)
参数
- str -- 要被分解成一组小字符串的字符串。
- delim -- 包含分隔符的 C 字符串。
返回值
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
模拟实现
char* my_strtok_sim(char* str, const char* delim)
{
static char* p = NULL; // 保存上次分割的位置
if (str != NULL)
{
p = str; // 如果是第一次调用,初始化p为str
} else if (p == NULL)
{
return NULL; // 如果p为空,表示已经完成了所有的分割,返回NULL
}
// 跳过分隔符
while (*p != '\0' && strchr(delim, *p) != NULL)
{
p++;
}
if (*p == '\0')
{
return NULL; // 如果p指向字符串结尾,表示已经完成了所有的分割,返回NULL
}
char* start = p; // 记录子字符串的起始位置
while (*p != '\0' && strchr(delim, *p) == NULL)
{
p++;
}
if (*p != '\0')
{
*p = '\0'; // 将分隔符替换为字符串结尾符,以便于后续调用
p++;
}
return start; // 返回子字符串的起始位置
}
七、memcpy
描述
C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1。
声明
下面是 memcpy() 函数的声明。
void* memcpy(void* dest, const void* src, size_t n)
参数
- dest -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- src -- 指向要复制的数据源,类型强制转换为 void* 指针。
- n -- 要被复制的字节数。
返回值
该函数返回一个指向目标存储区 dest 的指针。
模拟实现
void* my_memcpy(void* dest, const void* src, size_t n)
{
char* dest_ptr = (char*) dest;
const char* src_ptr = (const char*) src;
for (size_t i = 0; i < n; i++)
{
dest_ptr[i] = src_ptr[i];
}
return dest;
}
八、memmove
描述
C 库函数 void *memmove(void *str1, const void *str2, size_t n) 从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。
声明
下面是 memmove() 函数的声明。
void* memmove(void* dest, const void* src, size_t num)
参数
- dest -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- src -- 指向要复制的数据源,类型强制转换为 void* 指针。
- num -- 要被复制的字节数。
返回值
该函数返回一个指向目标存储区 dest 的指针。
模拟实现
void* my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
if (dest < src)
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
while (num--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return(ret);
}