目录
1. strlen
strlen函数是求出字符串的长度以'\0'为结束标志,测得的字符串的长度就是strlen的返回值,'\0'不算纳入计算。下面的代码就是'\0'的位置不同,测出的长度就不同。
#include<stdio.h>
#include<string.h>
int main()
{
char ch1[] = { '1','2','3','4','\0'};
char ch2[] = "ab\0cd";
int ret1 = strlen(ch1);
int ret2 = strlen(ch2);
printf("%d\n", ret1); //4
printf("%d\n", ret2); //2
return 0;
}
模拟实现strlen函数
int my_strlen(const char* str)
{
assert(str);
int count = 0;
while (*str != '\0')
{
str++;
count++;
}
return count;
}
2. strcpy
1.源字符串必须以 '\0' 结束。
2.会将源字符串中的 '\0' 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4.目标空间必须可变。
实现的就是函数参数的后一个字符串拷贝到前一个。
#include<stdio.h>
#include<string.h>
int main()
{
char ch1[] = "abcde";
char ch2[20];
strcpy(ch2, ch1);
printf("%s\n", ch2); //abcde
return 0;
}
模拟实现
char* my_strcpy(char* str1,const char* str2)
{
assert(str1 && str2);
char* ret = str1;
while (*str1++ = *str2++)
{
;
}
return ret;
}
3. strcat
strcat是字符串的连结,就是后者的字符串接到前者的字符串上去。
#include<stdio.h>
#include<String.h>
int main()
{
char ch1[20] = "abcde";
char ch2[20] = "12345";
strcat(ch1, ch2);
printf("%s\n", ch1); //abcde12345
return 0;
}
模拟实现
char* my_strcat(char* ch1,const char* ch2)
{
assert(ch1 && ch2);
char* ret = ch1;
while (*ch1)
{
ch1++;
}
while (*ch1++ = *ch2++)
{
;
}
return ret;
}
4. strcmp
#include<stdio.h>
#include<string.h>
int main()
{
char ch1[] = "abcde";
char ch2[] = "abq";
int ret = strcmp(ch1, ch2);
printf("%d\n", ret); //-1
return 0;
}
字符串的比较,字符串的每一位一一比较,如果前者大就返回1,相等返回0,后者大就返回-1.
1也可以理解成比零大的数,-1是比零小的数,
模拟实现
int my_strcmp(const char* ch1,const char* ch2)
{
assert(ch1 && ch2);
while (*ch1 == *ch2)
{
if (*ch1 == '\0')
{
return 0;
}
ch1++;
ch2++;
}
return *ch1 - *ch2;
}
5. strncpy
strncpy就是多一个参数来指定拷贝的大小。
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "xxxxxxxxxxxxxx";
strncpy(arr1, "abcdef", 5);
printf("%s\n", arr1); //abcdexxxxxxxxx
return 0;
}
6. strncat
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abc\0xxxxxxxx";
strncat(arr1, "defqwer", 4);
printf("%s\n", arr1);
return 0;
}
加上参数,输入几就是接上的字符串要几个字符。
7. strncmp
#include<stdio.h>
#include<string.h>
int main()
{
char* p1 = "abcdef";
char* p2 = "abcqwer";
int ret = strncmp(p1, p2, 4);
printf("%d\n", ret);
return 0;
}
输入参数,输入几就是比较前多少个字符。
8. strstr
这个函数是用来匹配字符串的,比如下图两个字符串如果有重复的就返回较长的一个的字符串首元素的地址。
char ch1[] = "abbbcde";
char ch2[] = "bbc";
模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
if (*str2 == '\0')
{
return str1;
}
char* s1 = NULL;
char* s2 = NULL;
char* cp = str1;
while (*cp)
{
s1 = cp;
s2 = str2;
if (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*str2 == '\0')
{
return (char*)cp;
}
cp++;
}
return NULL;
}
int main()
{
char ch1[] = "abbbcde";
char ch2[] = "bbc";
my_strstr(ch1, ch2);
return 0;
}
9. mencpy
memcpy是两个数组的拷贝,不仅仅限于字符数组,对于整型,浮点型都是可以的。
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[20] = { 0 };
int sz = sizeof(arr1) / sizeof(arr1[0]);
memcpy(arr2, arr1, 20);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
memcpy实现的是将arr1的数组的前面20个字节赋给arr2,对于整型也就是赋值前面五个元素,所以打印的结果就是1,2,3,4,5,0,0,0,0,0 .
模拟实现
#include<stdio.h>
void* my_memcpy(void* dest,const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
10. memmove
memmove其实是前面memcpy的升级版,可以进行重叠拷贝。
模拟实现
#include<stdio.h>
void* my_memmove(void* dest, void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
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;
}
对于memmove的实现需要分两种情况,当有重合的时候是从前往后拷贝,还是从后往前拷贝,这就是实现这个函数的关键,代码已经给了,自己看看就能懂。
11. memcmp
memcmp是比较大小,和前面一样返回一个值,很容易理解举个例子就行。
#include<stdio.h>
int main()
{
int arr1[] = { 1,2,6 };//01 00 00 00 02 00 00 00 06 00 00 00
int arr2[] = { 1,2,5 };//01 00 00 00 02 00 00 00 05 00 00 00
int ret = memcmp(arr1, arr2, 9);
printf("%d\n", ret);
return 0;
}