一. strlen函数
参数类型:
size_t strlen ( const char * str );
注意事项:
1. 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
2.参数指向的字符串必须要以 ‘\0’ 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )
#include <stdio.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;
}
因为strlen点的返回值是size_t (unsigned int),所以两个返回值相减依旧是unsigned int 型,是一个无符号的整数,也就是大于零。
strlen函数的模拟实现:
int main()
{
char arr[] = "panzii666";
char* parr = arr;
int count = 0;
while (*parr != '\0')
{
++parr;
count++;
}
printf("%d", count);
return 0;
}
二.strcpy函数
参数类型:
char* strcpy(char * destination, const char * source );
注意事项:
1.源字符串必须以 ‘\0’ 结束。
2.会将源字符串中的 ‘\0’ 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。目标空间必须可变。
char* my_strcpy(char* dest,char* src)
{
char* ret = dest;
while(*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
return ret;
}
int main()
{
char arr1[20] = "panzii666";
char arr2[10] = "xxxxx";
char*ret= my_strcpy(arr1,arr2);
printf("%s", arr1);
return 0;
}
三.strcat函数
参数类型:
char * strcat ( char * destination, const char * source );
注意事项:
1.源字符串必须以 ‘\0’ 结束。
2.目标空间必须有足够的大,能容纳下源字符串的内容。目标空间必须可修改。
3.自己给自己追加如何?
答案:trcat函数在执行追加操作时需要依赖null字符来确定字符串的末尾位置,否则它就无法正确地将字符串追加到目标字符串的末尾。
如果你试图将一个字符串追加到自身,那么源字符串的末尾将不再是null字符,而是源字符串的最后一个字符。这将导致strcat函数无法正确判断目标字符串的末尾位置,可能会导致错误的结果或者内存溢出。
strcat 函数的模拟:
char* my_strcat(char* dest, char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest != '\0')
{
dest++;
}
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
return ret;
}
int main()
{
char arr1[20] = "panzii666";
char arr2[10] = "xxxxx";
my_strcat(arr1, arr2);
printf("%s", arr1);
return 0;
}
四.strcmp函数
参数类型:
int strcmp ( const char * str1, const char * str2 );
注意事项:
1.第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
strcmp函数的模拟:
int my_strcmp(char* arr1, char* arr2)
{
while (*arr1==*arr2)
{
if (*arr1 == '\0')
return 0;
arr1++;
arr2++;
}
if (*arr1 > *arr2)
return 1;
else
return -1;
}
int main()
{
char arr1[20] = "panzii666";
char arr2[10] = "xxxxx";
int ret= my_strcmp(arr1, arr2);
printf("%d", ret);
return 0;
}
五.strstr函数
参数类型:
char * strstr ( const char *str1, const char * str2);
注意事项:
1.这是一个查找字符串的函数,在第一个字符串中查找第二个字符串,并且返回第一次找到完整的第二个字符串的首地址。
a b b b c d e f
b b c
模拟实现strstr函数:
char* my_strstr(char* arr1,char* arr2)
{
char* s1 = arr1;
char* cp = s1;
char* s2 = arr2;
while (*cp)
{
s1 = cp;
s2 = arr2;
while(*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
return cp;
cp++;
}
return NULL;
}
int main()
{
char arr1[] = "abbbcdef";
char arr2[] = "bbc";
char* ret=my_strstr(arr1, arr2);
printf("%s", ret);
return 0;
}
六.strtok函数
参数类型:
char * strtok ( char * str, const char * sep );
注意事项:
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
1.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-"); }
return 0;
}
#include <stdio.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);
}
}
这个for循环在这里用的非常的妙,将一段重复的代码用for循环完美解决。
七.内存函数memcpy
参数类型:
void * memcpy ( void * destination, const void * source, size_t num );
注意事项:
1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
2.这个函数在遇到 ‘\0’ 的时候并不会停下来。
3.如果source和destination有任何的重叠,复制的结果都是未定义的。
4.memcpy也可以实现memmove的功能,不过是在源地址在目标地址之后用这个函数才可以实现。
void * memcpy ( void * destination, const void * source, size_t num );
#include<stdio.h>
void* my_memcpy(void* dest, const void* src, size_t num){
void* ret = dest;
while (num--)
{
*((char*)dest) = *((char*)src);
dest = ++(char*)dest;
src = ++(char*)src;
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
my_memcpy(arr2, arr1, 40);//这里40代表字节,而不是个数
for (int i = 0; i < 20; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
八. 内存函数memmove
参数类型:
void * memmove ( void * destination, const void * source, size_t num );
注意事项:
1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。
如图:
从后往前
前:1 2 5 6 7 8 9 8 9 10
后:1 2 1 2 3 4 5 8 9 10
从前往后:
前:1 2 3 4 5 6 7 8 9 10
后:1 2 1 2 3 4 5 8 9 10
#include<string.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
if (src > dest)
{
void* ret = dest;
while (num--)
{
*((char*)dest) = *((char*)src);
dest = ++(char*)dest;
src = ++(char*)src;
}
return ret;
}
else if(src < dest)
{
void* ret = dest;
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
else
{
return 0;
}
return ret;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr , arr+2, 20);从前往后
//my_memmove(arr+2, arr, 20);从后往前
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
这张图分为三种情况:
九.内存函数 memcpy
类型参数:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
注意事项:
1.比较从ptr1和ptr2指针开始的num个字节
2.返回值如下:第一个字符串>第二个字符串 >0的数字
第一个字符串<第二个字符串 <0的数字
第一个字符串=第二个字符串 0
#include <stdio.h>
#include <string.h>
int main ()
{
char buffer1[] = "DWgaOtP12df0"; char buffer2[] = "DWGAOTP12DF0";
int n;
n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
if (n>0)
printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
else if (n<0)
printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
return 0;
}
希望对大家有所帮助,大家多多支持我吧!谢谢!