目录
1.求字符串长度
1.1 strlen函数
size_t strlen ( const char * str );
作用:从起始位置以‘\0’作为结束标志,返回‘\0’前的字符个数。
参数:一个char* 类型的指针,
返回类型:size_t 无符号的
注意事项:指针指向的字符串必须是以‘\0’结尾的。
1.2 模拟实现strlen函数
size_t my_strlen(const char* arr)
{
assert(arr);
int count = 0;
while (*arr != '\0')
{
count++;
arr++;
}
return count;
}
int main()
{
char arr[] = "abcdefg";
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
assert() 用于断言,判断传入是否为空指针,是则报错。
使用时需要包含头文件include<assert.h>
2.长度不受限制的字符串函数
2.1.1 strcpy函数
char* strcpy(char * destination, const char * source );
作用:将源字符串内容拷贝到指定字符串中。
参数:两个char*的指针。
返回类型:char* 为了实现链式访问
注意事项:
① 源字符串需以‘\0’结束。
② strcpy函数会将源字符串的‘\0’一起拷入到目标空间
③ 目标空间必须足够大且可变,以确保能存放源字符串。
2.1.2模拟实现strcpy函数
char* my_strcpy(char* arr1, const char* arr2)
{
assert(arr1);
assert(arr2);
char* str = arr1;
while ((*arr1++ = *arr2++))
{
;
}
return str;
}
int main()
{
char arr1[20] = "helloworld";
char arr2[] = "****";
printf("%s\n", my_strcpy(arr1, arr2));
return 0;
}
2.2.1 strcat函数
char * strcat ( char * destination, const char * source );
作用:将源字符串追加到指定字符串后。
参数:两个char*的指针。
返回类型:char*
注意事项:
① 源字符串需以‘\0’结束。
②从源字符串的‘\0’位置开始追加。
③ 目标空间必须足够大且修改,以存放源字符串内容。
④ 不能自己给自己追加。
2.2.2模拟实现strcat函数
char* my_strcat(char* arr1,const char* arr2)
{
assert(arr1);
assert(arr2);
char* str = arr1;
while (*arr1 != '\0')
{
arr1++;
}
while (*arr1++ = *arr2++)
{
;
}
return str;
}
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
printf("%s\n",my_strcat(arr1, arr2));
return 0;
}
2.3.1 strcmp函数
int strcmp ( const char * str1, const char * str2 );
作用:比较两个字符串它对应位置上字符的大小,而非长度。
参数:两个char*的指针。
返回类型:int
注意事项:
2.3.2模拟实现strcmp函数
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1);
assert(arr2);
while (*arr1 == *arr2)
{
if (*arr1 == '\0' || *arr2 == '\0')
return 0;
arr1++;
arr2++;
}
if (*arr1 > *arr2)
{
return 1;
}
else
return -1;
}
int main()
{
char arr1[] = "abdef";
char arr2[] = "abd";
int ret = my_strcmp(arr1, arr2);
if (ret == 0)
printf("相等\n");
else if (ret == 1)
printf("大于\n");
else
printf("小于\n");
return 0;
}
3.长度受限制的字符串函数
3.1.1 strncpy函数
char * strncpy ( char * destination, const char * source, size_t num );
作用:从源字符串拷贝num个字符到目标空间。
参数:两个char*的指针;一个无符号类型的num,表示要拷贝的字节数
返回类型:char*
注意事项:
如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
3.1.2 模拟实现strncpy函数
char* my_strncpy(char* arr1, const char* arr2, size_t num)
{
assert(arr1);
assert(arr2);
char* str = arr1;
while (num && (*arr1++ = *arr2++) != '\0')
{
num--;
}
if (num != 0)
{
*arr1 = '\0';
num--;
}
return str;
}
int main()
{
char arr1[] = "hello world";
char arr2[] = "####";
printf("%s\n",my_strncpy(arr1, arr2, 4));
return 0;
}
3.2.1 strncmp函数
int strncmp(const char * destination, const char * source, size_t num );
作用:比较两个字符串它对应位置上字符的大小,比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
参数:两个char*的指针;一个无符号类型的num,表示要比较的字节数
返回类型:int
注意事项:
3.2.2 模拟实现strncmp函数
int my_strcmp(const char* arr1, const char* arr2,size_t num)
{
assert(arr1);
assert(arr2);
while (num && (*arr1 != '\0' || *arr2 != '\0'))
{
if (*arr1 == *arr2)
{
arr1++;
arr2++;
num--;
}
else if (*arr1 > *arr2)
return 1;
else
return -1;
}
return 0;
}
int main()
{
char arr1[] = "abdef";
char arr2[] = "abdeq";
int ret = my_strcmp(arr1, arr2,5);
if (ret == 0)
printf("相等\n");
else if (ret == 1)
printf("大于\n");
else
printf("小于\n");
return 0;
}
3.3.1 strncat函数
char * strncat ( char * destination, const char * source, size_t num );
作用:将源字符串num个字节内容追加到指定字符串后。
参数:两个char*的指针;一个无符号类型的num
返回类型:char*
注意事项:可以自己给自己追加。
3.3.2模拟实现strncat函数
char* my_strcat(char* arr1,const char* arr2,size_t num)
{
assert(arr1);
assert(arr2);
char* str = arr1;
while (*arr1 != '\0')
{
arr1++;
}
while (num && (*arr1++ = *arr2++)!='\0')
{
num--;
}
return str;
}
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
printf("%s\n", my_strcat(arr1, arr2,3));
return 0;
}
4.字符串查找
4.1.1 strstr函数
char * strstr ( const char *str1, const char * str2);
作用:在目标字符串中查找源字符串是否存在。
参数:两个char*的指针。
返回类型:char*
存在:返回子串第一次出现的位置
不存在:返回 NULL
4.1.2模拟实现strsr函数
char* my_strstr(const char* arr1, const char* arr2)
{
const char* s1 = arr1;
const char* s2 = arr2;
const char* p = arr1;
if (*arr2 == '\0')
{
return arr1;
}
while (*p)
{
s1 = p;
s2 = arr2;
while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
return p;
p++;
}
return NULL;
}
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "abc";
char* ret = my_strstr(arr1, arr2);
if(ret==NULL)
printf("不存在\n");
else
printf("%s\n", ret);
return 0;
}
4.2.1 strtok函数
char * strtok ( char * str, const char * sep );
作用:strtok函数找到str中的下一个标记,并将其用\0 结尾,返回一个指向这个标记的指针。即找到第一个分割符,用\0替换它,返回起始位置的地址
参数:sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
返回类型:char*
注意事项:
① strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容。
5.错误信息报告
strerror函数
char * strerror ( int errnum );
功能:返回错误码,所对应的错误信息。
注意:头文件是<errno.h>
6.内存操作函数
6.1.1 memcpy函数
void * memcpy ( void * destination, const void * source, size_t num );
作用:从source的位置开始向后复制num个字节的数据到destination的内存位置。
参数:两个void*的指针;一个无符号类型的num
返回类型:void*
注意事项:
6.1.2模拟实现memcpy函数
void* my_memcpy(void* str1, const void* str2, size_t num)
{
void* str = str1;
while (num)
{
*((char*)str1)++ = *((char*)str2)++;
num--;
}
return str;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr1, arr2, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
6.2.1 memmove函数
void * memmove ( void * destination, const void * source, size_t num );
与memcpy函数相同
区别:memmove函数处理的源内存块和目标内存块是可以重叠的。
6.2.2模拟实现memmove函数
void* my_memmove(void* dest, void* src, size_t num)
{
void* str = dest;
if (dest < src)
{
while (num)
{
*((char*)dest)++ = *((char*)src)++;
num--;
}
}
else
{
while (num)
{
*((char*)dest+num) = *((char*)src+num);
num--;
}
}
return str;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr + 1, arr, 10);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
6.3memcmp函数
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
6.4 memset函数
void * memset ( void * destination, int c,size_t num );