文章目录
前言
本文是 继续 字符函数和字符串函数
上文 链接
字符串和字符串函数 上
一、strstr
1.strstr函数
头文件<string.h>
2.描述
char *strstr(const char *haystack, const char *needle)
在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 '\0'。
haystack -- 要被检索的 主 字符串。
needle -- 在 haystack 字符串内要搜索的子字符串。
.返回值
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。
2.strstr函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abbbcdef";
char arr2[10] = "bcd";
char* ret = strstr(arr1, arr2);
// strstr 函数 没找到 会 返回 空指针 NULL
if (ret == NULL)
{
printf("没找到\n");
}
else
{
printf("子字符串->: %s ", ret);
}
return 0;
}
3.strstr模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strstr(const char* arr1, const char* arr2)
{
assert(arr1 && arr2);
const char*s1 = NULL;
const char* s2 = NULL;
char* cp = arr1;
while (*cp)
{
s1 = cp;// cp 记录 arr1 的位置如果需要回退则会回到此位置
s2 = arr2;
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;
}
cp++;
}
}
int main()
{
char arr1[20] = "abbbcdef";
char arr2[10] = "bcd";
char* ret = my_strstr(arr1, arr2);
// strstr 函数 没找到 会 返回 空指针 NULL
if (ret == NULL)
{
printf("没找到\n");
}
else
{
printf("子字符串->: %s ", ret);
}
return 0;
}
花了草图思路 ,水平有限
只能将就看看了
二、strtok
1.strtok函数
原型
头文件 <string.h>
char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标
记
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
2.strtok的使用
#include<stdio.h>
#include<string.h>
// strtok 会将 第二个数组 中存放 的字符当分割标识
// 如 下面的" " "." "@" strtok 会改变 原来的数组
// 所以 可以先用 strcpy 先拷贝一份 然 让 strtok 分割
// 拷贝的数组 strtok 会先重左到右找到表示符号 并把标识符改成'\0'并将地址记住
// 返回 第一个元素地址,
//当第二个 参数 传的为NULL 函数将在同一个字符串中被保存的位置开始(上次记录的地址),查找下一个标
//记。
//int main()
//{
// char arr1[] = "wan quan@qq.haha";
// char* p = " .@";
// char tmp[20] = { 0 };
// strcpy(tmp, arr1);
// char* ret = NULL;
// ret = strtok(tmp, p);
// printf("%s\n", ret);
// ret = strtok(NULL, p);
// printf("%s\n", ret);
// ret = strtok(NULL, p);
// printf("%s\n", ret);
// ret = strtok(NULL, p);
// printf("%s\n", ret);
//
// return 0;
//}
//
int main()
{
char arr1[] = "wan quan@qq.haha";
char* p = " .@";
char tmp[20] = { 0 };
strcpy(tmp, arr1);
char* ret = NULL;
for (ret = strtok(tmp, p); ret != NULL; ret = strtok(NULL, p))
{
printf("%s \n", ret);
}
return 0;
}
三、 strerror
1.了解错误码的产生
使用库函数的时候
调用库函数失败时,都会生成错误码
全局错误码
int errno
给错误码赋予 5 我们很难知道啥意思
这是就要用到我们的库函数 strerror函数
会将错误码翻译成对应信息
2.strerror 函数
原型
char * strerror ( int errnum );
可以看见 函数的参数就是 错误码
3.strerror函数的使用
// 函数的使用往往与打开文件 有关 现在只是演示 函数的使用
int main()
{
printf("%s\n", strerror(0));
printf("%s\n", strerror(1));
printf("%s\n", strerror(2));
printf("%s\n", strerror(3));
printf("%s\n", strerror(5));
return 0;
}
四、内存拷贝函数(memcpy)
1.函数原型
头文件<string.h>
void * memcpy ( void * destination, const void * source, size_t num );
destination 目的地 source 源头 num 拷贝多少字节的空间
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 '\0' 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。
2.memcpy函数使用
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 10;i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
3.memcpy函数的模拟实现
// memcpy 函数的使用
// 内存拷贝函数 --- 头文件
// #include <string.h>
//size_t 无符号整数
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src); // 断言防止 dest src 为空指针
while (num--) // 先判断 20 不等于 0 然后 -- 等于 19进入循环
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
//memcpy(arr2, arr1, 20);
my_memcpy(arr2, arr1, 20);
for (int i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
五、memmove
1. 解决重叠问题
如果两 个数据 重叠
memmove 函数可以处理内存重叠 的情况
函数原型
void * memmove ( void * destination, const void * source, size_t num );
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
2.memmove 函数使用
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* stc, size_t num)
{
void* ret = dest;
assert(dest && stc);
while (num--)
{
*(char*)dest = *(char*)stc;
dest = (char*)dest + 1;
stc = (char*)stc + 1;
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
//memcpy(arr2, arr1, 20);
//my_memcpy(arr1+2, arr1, 20);
//调试后可以明显发现 我们 的 值被覆盖
// 原本我们想 打印 的值 为
// 1 2 1 2 3 4 5 8 9 10
// 调试后 我们 得到的 是
// 1 2 1 2 1 2 1 8 9 10
memmove(arr1 + 2, arr1, 20);
return 0;
}
使用 memmove 函数 后
可以发现 通过 memmove 函数 解决了 数组 在内存中重叠 覆盖的问题
3.memmove模拟实现
3 dest 与 str 不重叠时 不管 是 前 到 后 还是 后 到 前
其结果都是 一样
总结 如果 dest与 str 重叠 而且 dest 在 str 前面 则要用 前到后
反之 后 到 前
接下来用代码实现
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* stc, size_t num)
{
assert(dest && stc);
if (dest < stc)
{
//前--->后
while (num--)
{
*(char*)dest = *(char*)stc;
dest = (char*)dest + 1;
stc = (char*)stc + 1;
}
}
else
{
//后--->前
while (num--)
{
*((char*)dest + num) = *((char*)stc + num);
}
}
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
六、内存比较函数(memcmp)
1.初步了解memcmp 函数
原型 int memcmp ( const void * ptr1, const void * ptr2, size_t num );
与strcmp 差不多
大于 返回一个非零 的数
小于 返回 一个 负数
等于 发回 0
num 表示比较的字节
2.memcmp的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abdfeg";
int ret = memcmp(arr1, arr2, 3);
if (ret > 0)
{
printf("arr1 > arr2");
}
else if (ret < 0)
{
printf("arr1 < arr2");
}
else
{
printf("arr1 == arr2 ");
}
return 0;
}
3.memcmp函数模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_memcmp(const void* arr1, const void* arr2, size_t num)
{
assert(arr1 && arr2);
char* s1 = (char*)arr1;
char* s2 = (char*)arr2;
int ret = 0;
while (num-- && !(ret = (*s1) - (*s2)))
{
s1++;
s2++;
}
if (ret > 0)
{
return 1;
}
else if (ret < 0)
{
return -1;
}
return 0;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abdfeg";
int ret = my_memcmp(arr1, arr2, 3);
if (ret > 0)
{
printf("arr1 > arr2");
}
else if (ret < 0)
{
printf("arr1 < arr2");
}
else
{
printf("arr1 == arr2 ");
}
return 0;
}