字符串及字符操作总结:
一、strcpy
#include <stdio.h>
#include<Windows.h>
#include<assert.h>
char* My_strcpy(char* str1, char* str2)
{
char* ret = str1;
assert(str1 != NULL && str2 != NULL);
//拷贝的位置不同
while (*str1 != '\0')
{
str1++;
}
while ((*str1++ = *str2++) != '\0')
{
;
}
return ret;
}
int main()
{
char arr1[20] = "abcdef";
char *arr2 = "gh";
printf("%s\n", My_strcpy(arr1, arr2));
system("pause");
return 0;
}
二、strcat
头文件:
#include <string.h>
函数原型:
char *strcat (char *dest,const char *src)
函数描述:
strcat()会将参数src字符串拷贝到参数dest所指的字符串尾,第一个参数dest要有足够的空间来容纳要拷贝的字符串;
返回值:
返回dest字符串参数的起始地址;
例子:
#include <string.h>
#include <stdio.h>
int main(void)
{
char dest[30] = "Hello";
char src[] = "World";
strcat(dest, src);
printf("dest:[%s]\n", dest);
return 0;
}
得到的结果是:dest:[HelloWorld]
三、strstr
#include <stdio.h>
#include<Windows.h>
#include<assert.h>
char* My_strstr(char* str1, char* str2) {
assert(str1&&str2);
while (*str1 != *str2)
{
str1++;
}
char *p = str1;
while ((*str1)&&(*str2) && (*str1 == *str2))
{
str1++;
str2++;
}
if (*str2=='\0')
return p;
else
return 0;
}
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "bc";
int ret=My_strstr(arr1, arr2);
if (ret == 0)
printf("没找到\n");
else
{
printf("找到啦,位置是%p\n", ret);
printf("%s\n", ret);
}
system("pause");
return 0;
}
四、strchr
#include <stdio.h>
#include<Windows.h>
#include<assert.h>
cahr* My_strchr(char* str, int c)
{
assert(str);
while (*str)
{
if (*str == (char*)c)
{
return str;
}
else
str++;
}
return NULL;
}
int main()
{
char str1[] = "abcdef";
int ret=My_strchr(str1, 'c');
printf("出现的位置时:%p\n", ret);
system("pause");
return 0;
}
五、strcmp
#include<stdio.h>
#include<windows.h>
#include<assert.h>
int strcmp(char* str1, char* str2)
{
assert(str1&&str2);
int ret = 0;
while (*str1 != '\0' || *str2 != '\0')
{
ret = (*str1 - *str2);
str1++;
str2++;
}
if (ret > 0)
ret = 1;
else if(ret < 0)
ret = -1;
return ret;
}
int main()
{
char* str1 = "abcdef";
char* str2 = "bcdefh";
printf("%d\n", strcmp(str1, str2));
system("pause");
return 0;
}
六、memcpy
#include<stdio.h>
#include<windows.h>
#include<assert.h>
char* my_memcpy(char* str1, char* str2, int count)
{
char* ret = str1;
while (count != 0 && *str2!='\0')
{
*ret = *str2;
ret++;
str2++;
count--;
}
return str1;
}
int main()
{
char str1[20] = "abcdef";
char* str2 = "higklmn";
printf("%s\n", my_memcpy(str1, str2,4));
system("pause");
return 0;
}
七、memmove
头文件:<string.h>
原型:void *memmove( void* dest, const void* src, size_t count );
函数作用:
用于从src拷贝count个字节到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域区域的字节拷贝到目标区域中,但复制后src内容会被更改,但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
memmove可以被分为三种情况:
1.dest<src,源内存的首地址大于目标内存的首地址,进行正向拷贝,此时无需担心dest+count>src,超出的部分只会将src已经拷贝过的部分覆盖,不会造成影响
2.dest>=src+count,此时目标内存的首地址大于源内存的首地址+count,进行反向拷贝,由于两首地址相距足够大,无需担心被覆盖问题
3.dest<src+count,此时目标内存的首地址小于源内存的首地址+count,此时随着src向dest拷贝,src前段会将末端的覆盖掉,导致数据丢失,此时我们需要手动“扩容”,将两个指针同时增加count-1
库函数实现:
#include <stdio.h>
#include<Windows.h>
#include<assert.h>
void * memmove(void *dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char*)dst >= ((char*)src + count))
{
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else{
dst = (char*)dst - 1;
src = (char*)src - 1;
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return(ret);
}
int main()
{
char src[] = "hello";
char dst[] = "hahha world";
memmove(dst, src, strlen(src));
printf("%s\n", dst);
system("pause");
return 0;
}
运行结果: