一.字符函数和字符串函数
1.前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没用字符串类型的,字符串通常放在常量字符串中或者字符数组中。
字符串常量适用于那些对它不做修改的字符串函数。
2.函数介绍
1.strlen(计算字符串长度)
字符串以及将'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数
(不包括'\0')。
参数指向的字符串必须要以'\0'结束。
注意!!!strlen函数的返回值类型是size_t,是无符号的!!!!
strlen函数模拟代码实现:
#include<stdio.h>
int my_strlen(char*arr)
{
char* p=arr;
int num = 0;
while (*p!='\0')
{
p++;
num++;
}
return num;
}
int main()
{
char arr[20] = "abcdrfgh";
int len=my_strlen(arr);
printf("%d\n", len);
return 0;
}
2.strcpy(字符串拷贝函数)
函数功能:能将字符源source拷贝到目标字符串destination中。
注意事项:源字符必须以'\0'结束,函数会将源字符中的'\0'拷贝到目标空间中,目标空间必须足够大以确保能存放源字符串。目标空间必须可变。注意!!返回类型为char*类型,函数返回destination的首元素地址。
strcpy函数模拟代码实现:
#include<stdio.h>
char* my_strcpy(char*dest,char*src)
{
char* ret = dest;
while (*dest++=*src++) //当src指向'\0'赋给dest,循环结束。
{
;
}
return ret;
}
int main()
{
char arr1[20] = "abc";
char arr2[] = "hello bit";
my_strcpy(arr1,arr2);
printf("%s\n",arr1);
return 0;
}
3.strcat(字符串追加函数)
函数功能:将源字符串source追加到目标字符串destination后面。
注意事项:源字符串必须以'\0'结束。
目标空间必须有足够的大,能容下源字符串的内容。
目标空间必须可修改。
注意!!!!函数返回类型为char*类型,且从'\0'开始追加。
strcat函数模拟代码实现:
#include<stdio.h>
char* my_strcat(char*dest, const char*src) //加const,源字符串无法修改
{
char *ret = dest;
//1.先找到目标字符串的'\0',"hello \0"
while (*ret!='\0')
{
ret++;
}
//2.拷贝源头数据到\0之后的空间
while (*ret++=*src++)
{
;
}
return dest; //函数返回目标字符串的首地址,为*char类型
}
int main()
{
char arr1[20] = "hello ";
char arr2[] = "world";
my_strcat(arr1,arr2);
printf("%s",arr1);
return 0;
}
4.strcmp(字符串比较函数)
函数功能:比较两个字符串的大小,比较的是ASCII码值。
标准规定:第一个字符串大于第二个字符串,则返回大于0的数字。
第一个字符串等于第二个字符串,则返回0。
第一个字符串小于第二个字符串,则返回小于0的数字。
注意!!!函数返回的是int类型,且比较的是字符的ASCII码值。
strcmp函数模拟代码实现:
#include<stdio.h>
int my_strcmp(char* arr1, char* arr2)
{
char*str1 = arr1;
char*str2 = arr2;
while (*str1 == *str2)
{
if (*str1=='\0')
{
return 0;
}
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = "abc";
char arr2[] = "abc";
int ret=my_strcmp(arr1,arr2);
printf("%d",ret);
return 0;
}
5.strstr(查找字符串函数)
函数功能:在字符串str1中查找字符串str2。
标准规定:在字符串str1中查找字符串str2,找到,返回str2的地址
没找到,返回空指针NULL。
注意!!!返回类型为char*类型。
strstr函数模拟代码实现:
#include<stdio.h>
char* my_strstr(const char*arr1,const char*arr2)
{
const char*str1 = arr1;
const char*str2 = arr2;
const char*p = arr1;
while (*p) //当p 指向'\0',循环结束,即遍历整个字符串。
{
str1 = p;
str2 = arr2;
while (*str1==*str2&&*str1!='\0'&&str2!='\0') //相等,str1,str2指针后移。
{
str1++;
str2++;
}
if (*str2 == '\0') //当str2指向'\0',即找到了所要找的字符串,返回p。
{
return (char*)p;
}
p++; //不相等,指针p后移,因为str1 = p; ,所以str1会随之p的移动而移动.
}
}
int main()
{
char arr1[] = "abcdedfga";
char arr2[] = "ded";
char*str=my_strstr(arr1,arr2);
printf("%s",str);
return 0;
}
二.字符函数和字符串函数
1.memcpy(内存拷贝函数)
函数功能:从source的位置开始向后复制num个字节的数据到destination的内存位置。
注意事项:函数遇到'\0'的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。
注意!!memcpy函数调用和返回的参数都是void*类型的,与strcpy不同的,它可以拷贝任意类型的参数。
memcpy函数的代码实现;
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void*dest,const void*src,size_t num)
{
void *ret = dest;
assert(dest);
assert(src);
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int arr2[10] = { 0 };
my_memcpy(arr2,arr1,20);
int i = 0;
for (i = 0; i < 10;i++)
{
printf("%d",arr2[i]);
}
printf("\n");
float arr3[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };
float arr4[10] = { 0.0 };
my_memcpy(arr4, arr3, 12);
int j = 0;
for (j = 0; j < 10; j++)
{
printf("%f ", arr4[j]);
}
return 0;
}
2.memmove(字符串移动拷贝函数)
函数功能:将num字节的源字符串source拷贝到目标字符串destination中。
注意事项:和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
代码编写思路图:
函数模拟代码实现:
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest);
assert(src);
void *ret = dest;
if (dest<src) //dest在src前面,先拷贝前面的
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else //destzai src后面,先拷贝后面的
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main()
{
int arr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 ,9};
my_memmove(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d", arr1[i]);
}
return 0;
}