目录
2.strcpy(), strcat(), strcmp()
3.strncpy(), strncat(), strncmp()
6.内存函数:memcpy()、memmove()、memset()、memcpy()
1.strlen()
>>>函数介绍
>>> 易错点举例
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
int main()
{
const char*str1 = "abcdef";
const char*str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0) //无符号数-无符号数结果还是一个无符号数
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
>>> 标准库函数源代码
size_t __cdecl strlen (
const char * str
)
{
const char *eos = str;
while( *eos++ ) ;
return( eos - str - 1 );
}
>>>模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
//计数器法
int my_strlen(const char* str)
{
int count = 0;
assert(str != NULL);
while (*str++ != '\0')
count++;
return count;
}
//递归法
int my_strlen2(const char* str)
{
assert(str != NULL);
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str + 1);
}
//指针-指针法
int my_strlen3(const char* str)
{
assert(str != NULL);
const char* pc = str;
while (*pc != '\0')
pc++;
return pc - str;
}
int main()
{
char* str = "aabcd";
int len = my_strlen(str);
printf("%d\n", len);
return 0;
}
2.strcpy(), strcat(), strcmp()
>>> 函数介绍
>>>易错点举例
//下面程序错误----目的字符串必须是可变的
#include <stdio.h>
#include <string.h>
//#include <assert.h>
int main()
{
char* p1 = "#########";
char* p2 = "abc";
//strcat(p1, p2); //运行出错,因为p1是常量字符串
strcpy(p1, p2); //运行出错,因为p1是常量字符串
printf(p1);
return 0;
}
//下面程序错误
#include <stdio.h>
#include <string.h>
//#include <assert.h>
int main()
{
char p1[20] = "abcd";
strcat(p1, p1); //运行出错,因为找不到\0结束
printf(p1);
return 0;
}
>>>标准库函数源代码
//strcpy标准库函数源代码
char * __cdecl strcpy(char * dst, const char * src)
{
char * cp = dst;
while((*cp++ = *src++) != '\0')
; /* Copy src over dst */
return( dst );
//strcat标准库函数源代码
char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while((*cp++ = *src++) != '\0') ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
//strcmp的标准库函数源代码
int __cdecl strcmp (
const char * src,
const char * dst
)
{
int ret = 0 ;
while((ret = *(unsigned char *)src - *(unsigned char *)dst) == 0 && *dst)
{
++src, ++dst;
}
return ((-ret) < 0) - (ret < 0); // (if positive) - (if negative) generates branchless code
}
>>> 模拟实现
//strcpy的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
char* pc = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))
{
;
}
return pc;
}
int main()
{
char p1[20] = {0};
char* p2 = "abcde";
my_strcpy(p1, p2);
printf(p1);
return 0;
}
//strcat的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
char* pc = dest;
assert(dest != NULL);
assert(src != NULL);
while (*dest)
dest++;
while ((*dest++ = *src++));
return pc;
}
int main()
{
char p1[20] = "qwer";
char* p2 = "abcd";
my_strcat(p1, p2);
printf(p1);
return 0;
}
//strcmp的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
//方法1
int my_strcmp1(char* str1, const char* str2)
{
assert(str1 != NULL);
assert(str2 != NULL);
while (*str1 || *str2)
{
if (*str1 == *str2)
{
str1++;
str2++;
}
else
{
return *str1 - *str2;
}
}
return 0;
}
//方法2
int my_strcmp2(char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
//方法3
int my_strcmp(const char * src, const char * dst)
{
int ret = 0;
assert(src != NULL);
assert(dst != NULL);
while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
if (ret < 0)
ret = -1;
else if (ret > 0)
ret = 1;
return(ret);
}
int main()
{
char p1[20] = "abcde";
char* p2 = "abcd";
int ret = my_strcmp(p1, p2);
//printf("%d", ret);
if (ret > 0)
printf("p1 > p2\n");
else if (ret < 0)
printf("p1 < p2\n");
else
printf("p1 = p2\n");
return 0;
}
3.strncpy(), strncat(), strncmp()
>>> 函数介绍
>>> 例子
//strncmp案例
#include <stdio.h>
#include <string.h>
int main()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts("Looking for R2 astromech droids...");
for (n = 0; n < 3; n++)
if (strncmp(str[n], "R2xx", 2) == 0)
{
printf("found %s\n", str[n]);
}
return 0;
}
4.strstr()
>>> 函数介绍
>>>标准库函数源代码
//strstr的标准库函数源代码
char * __cdecl strstr (
const char * str1,
const char * str2
)
{
char *cp = (char *) str1;
char *s1, *s2;
if ( !*str2 )
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *) str2;
while ( *s2 && !(*s1-*s2) )
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}
>>> 模拟实现
//strstr的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
//方法1
char* my_strstr1(const char* str1, const char* str2)
{
assert(str1 && str2);
char* s1 = str1;
char* s2 = str2;
if (!*str2)
return str1;
while (*str1)
{
if (*str1 == *str2)
{
str1++;
str2++;
}
else
{
s1++;
str1 = s1;
str2 = s2;
}
if (*str2 == '\0')
return s1;
}
return NULL;
}
//方法2
char * my_strstr(const char * str1, const char * str2)
{
assert(str1 && str2);
char *cp = (char *)str1;
char *s1, *s2;
if (!*str2)
return ((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *)str2;
while (*s1 && *s2 && !(*s1 - *s2))
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return NULL;
}
int main()
{
char* p1 = "abcaabbcd";
char* p2 = "bcd";
char* pc = my_strstr(p1, p2);
printf(pc);
return 0;
}
5.strtok()
>>>函数介绍
char* strtok( char* str, const char* sep);
** sep参数是个字符串,定义了用作分隔符的字符集合
** 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
** strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
** strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
** strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
** 如果字符串中不存在更多的标记,则返回 NULL 指针。
>>>例子
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "zhangpengwei@bitedu.tech";
const char* sep = ".@";
char arr[30];
char *str = NULL;
strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
{
printf("%s\n", str);
}
}
6.内存函数:memcpy()、memmove()、memset()、memcpy()
>>>函数介绍
>>>模拟实现
//memcpy的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t n)
{
assert(dest && src);
void* pc = dest;
while (n--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return pc;
}
int main()
{
int a1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int a2[10] = { 0 };
my_memcpy(a2, a1, 20);
for (int i = 0; i < 10; i++)
printf("%d ", a2[i]);
return 0;
}
//memmove的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t n)
{
assert(dest && src);
void* pc = dest;
if (dest < src)
{
//前-->后
while (n--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//后-->前
while (n--)
*((char*)dest + n) = *((char*)src + n);
}
return pc;
}
int main()
{
int a1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
my_memmove(a1 + 2, a1, 20);
for (int i = 0; i < 10; i++)
printf("%d ", a1[i]);
return 0;
}