有没有悬赏做ppt的网站,wordpress d8 3.0,软件编程,网站建设成本核算八. strstr函数
1.strstr的定义
char *strstr( const char *str1, const char *str2 );
-1. strstr查找子串(str2)在字符串(str2)中第一次出现的位置#xff0c;记录并返回该位置的指针#xff0c;如果找不到#xff0c;则返回NULL
-2. str1#xff1a;查找字符…八. strstr函数
1.strstr的定义
char *strstr( const char *str1, const char *str2 );
-1. strstr查找子串(str2)在字符串(str2)中第一次出现的位置记录并返回该位置的指针如果找不到则返回NULL
-2. str1查找字符串的目标空间 str2需要查找的对象字符串
-3. 因为strstr函数操作时不会改变形参的指向所以我们在两个形参前面加上两个const
2.strstr的使用
例1
记录子串在目标字符串中的位置然后返回子串首地址
#include stdio.h
#include string.hvoid main(void)
{char* str1 Strive to improve yourself;char* str2 improve;char* det strstr(str1, str2);if(ret NULL){printf(字符串不存在);}else{printf(%s, det);}
}
运行结果 例2
返回子串首地址在目标字符串中的具体位置(地址 - 地址的方法)
#include stdio.h
#include string.hvoid main(void)
{char* str1 Strive to improve yourself;char* str2 improve;char* det strstr(str1, str2);int result det - str1 1;if (det NULL){printf(字符串不存在);}else{printf(%d, result);}
}
运行结果 例3
记录目标空间中一共出现多少次子串
#include stdio.h
#include string.hvoid main(void)
{char* str1 Strive to improve improve yourself;char* str2 improve;char* p str1;int count 0;while (p strstr(p, str2)){count;p;}printf(%d, count);
}
运行结果 3.strstr的模拟实现
#include stdio.h
#include assert.hchar* My_strstr(const char* str1, const char* str2)
{assert(str1 str2);char* p str1;char* s1 str1;char* s2 str2;while (*p){s1 p;s2 str2;while (*s1 ! \0 *s2 ! \0 *s1 *s2){s1;s2;}if (*s2 \0)return p;p;}return NULL;
}int main()
{char* str1 abbbcdf;char* str2 bbc;const char* det My_strstr(str1, str2);if (det NULL){printf(字符串不存在);}else{printf(%s, det);}return 0;
}
九. strtok函数
1.strtok的定义
char *strtok( char *strToken, const char *strDelimit );
-1. 作用:切割字符串。将分隔符转换成\0在将前面那个字符串的首地址返回给函数返回\0前面的字符串
-2. char *strToken 目标空间
-3. char *strDelimit 标记分隔符
2.strtok的使用
例1
#include stdio.h
#include string.hint main()
{const char* sep .;//三个分隔符 . \0 别忘了字符串还带有\0char email[] zhangsannianxi.nbaiwan;char cp[30] { 0 }; strcpy(cp, email); char *ret strtok(cp, sep);if(ret ! NULL){printf(%s , ret);}return 0;
}
因为strtok函数会改变原字符串中的内容所以一般都是使用临时拷贝的内容并且可修改
运行结果 strtok函数的第一个参数不为NULL函数将找到str中第一个标记strtok函数将保存它在字符串中的位置
为NULL函数将在同一个字符串中被保存的位置开始查找下一个标记
例2
#include stdio.h
#include string.hint main()
{const char* sep .;char email[] zhangsannianxi.nbaiwan;char cp[30] { 0 }; strcpy(cp, email); char *ret strtok(cp, sep);if(ret ! NULL){printf(%s\n, ret);}ret strtok(NULL, sep);if(ret NULL){printf(第二次没有找到该标记);}else{printf(%s\n, ret);}return 0;
}
如果两个标记在一起中间什么都没有函数strtok就啥也获取不到获取不到strtok会直接跳过
不管它直接去找下一个标记
运行结果 例3
第三次分割
#include stdio.h
#include string.hint main()
{const char* sep .;/* char email[] zhangsan.nianxinbaiwan;*/char email[] zhangsannianxi.nbaiwan;char cp[30] { 0 };strcpy(cp, email);char* ret strtok(cp, sep);if (ret ! NULL){printf(%s\n, ret);}ret strtok(NULL, sep);if (ret NULL){printf(第二次没有找到该标记);}else{printf(%s\n, ret);}ret strtok(NULL, sep);if (ret NULL){printf(第三次什么也没获取到);}else{printf(%s\n, ret);}return 0;
}
运行结果 例4
如果strtok什么都没找到就会返回NULL
第四次从字符串末尾开始向后找后面已经没有字符串了所以找不到
#include stdio.h
#include string.hint main()
{const char* sep .;/* char email[] zhangsannianxin.baiwan;*/char email[] zhangsannianxi.nbaiwan;char cp[30] { 0 };strcpy(cp, email);char* ret strtok(cp, sep);if (ret ! NULL){printf(%s\n, ret);}ret strtok(NULL, sep);if (ret NULL){printf(第二次没有找到该标记\n);}else{printf(%s\n, ret);}ret strtok(NULL, sep);if (ret NULL){printf(第三次什么也没获取到\n);}else{printf(%s\n, ret);}ret strtok(NULL, sep);if (ret NULL){printf(第四次什么也没获取到\n);}else{printf(%s\n, ret);}return 0;
}
运行结果 因为每次都需要用if else来判断有点重复不好看
所以我们将代码改进一下
利用for循环
#include stdio.h
#include string.hint main()
{const char *sep .;char email[] zhangsannianxin.baiwan;char pc[30] { 0 };strcpy(pc, email);char *ret 0;ret strtok(pc, sep);for(; ret ! NULL; ret strtok(NULL, sep)){printf(%s\n, ret);}return 0;
}
3.strtok的模拟实现
例1
#include stdio.h
#include string.h
#include assert.hchar* My_strtok(char* ps, const char* pc)
{assert(pc); //不用加上ps因为第二次用的话会传参NULLstatic char* str1 NULL;static char* str2 NULL;static int count 0;static int sz1 0; int sz2 0;if(ps ! NULL){str1 ps;sz1 strlen(ps);sz2 strlen(pc);for(*ps; *ps ! \0; ps){for(int i 0; i sz2; i){if(i 0){count;}if(*ps *(pc i)){*ps \0;str2 ps;return str1;}}}else{str1 str2 1;ps str1;for(*ps; *ps \0; ps){for(int i 0; i sz2; i){if(i 0){count;}if(*ps *(pc i)){ps \0;str2 psreturn str1;}}}if(count sz1){return NULL;}return str1;}
}
int main()
{const char* pc b;char email[] nianxinbaiwan;char ps[30] { 0 };strcpy(ps, email);char* ret My_strtok(ps, pc);for(; ret ! NULL; ret My_strtok(NULL, pc)){printf(%s\n, ret);}return 0;
}
十. strerror函数
1.strerror的定义
char *strerror( int errnum );
-1.返回值是字符型的指针
-2.int errnum 错误码C语言的数据库在执行失败的时候都会自动设置错误码
0:No error 1:Operation not permitted 2:No such file or directory 3:No such process 4:Interrupted function call 5:Input/output error 6:No such device or address 7:Arg list too long 8:Exec format error 9:Bad file descriptor
errno - C语言设置的一个全局的错误码存放的变量
2.strerror的使用
#include stdio.h
#include errno.hint main()
{FILE* pf fopen(idea.txt, w);if(pf NULL){printf(%d, strerror(errno));return 1;}fputc(w);fclose(pf);pf NULL;return 0;
}
运行结果 十一. 字符分类函数
包含头文件 ctype
1.isspace - 判断是否是空白字符是就返回非0不是就返回0
int a isspace( );
printf(%d, a); 2.isdigit - 判断是否是数字字符是就返回非0不是就返回0 int a isdigit(x);printf(%d, a); 3.iscntrl - 任何控字符
4.isxdigit - 十六进制数字包括十进制数字小写字母a - f大写字母A - F
5.islower - 小写字母a - z
6.isupper 大写字母A - Z
7.isalpha 字母a - z或A - Z
8.isalnum 字母或数字a - zA - Z0 - 9
9.ispunct 标点符号任何不属于数字或者字母的图形字符可打印
10.isgraph 任何图像字符
11.isprint 任何打印字符包括图形字符和空白字符
十二. tolower函数
1. tolower的使用
printf(%c\n, tolower(W)); 2.tosupper - 转大写
十三. memcpy
1.memcpy的定义
void* memcpy(void* destination, const void* source, size_t num);
万能copy函数什么类型的都可以拷贝
memcpy负责拷贝两块独立的空间中的数据
-1. void* destination 目标空间
-2. void* source 源空间
-3. size_t num 源空间总大小
2.memcpy的使用
例1
整型拷贝
#include stdio.h
#include string.hint main()
{int arr1[] {1, 2, 3, 4, 5, 6, 7, };int arr2[10] { 0 };memcpy(arr2, arr1, 28);int i 0;for(i 0; i sizeof(arr2)/sizeof(arr2[0]); i){printf(%d , arr2[i]);}return 0;
}
运行结果 例1
浮点型拷贝
#include stdio.h
#include string.hint main()
{float arr1[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, };float arr2[10] { 0.0 };memcpy(arr2, arr1, 28);int i 0;for (i 0; i sizeof(arr2) / sizeof(arr2[0]); i){printf(%d , arr2[i]);}return 0;
}
运行结果 tips strcpy和memcpy的区别 1.复制内容不同strcpy只能复制字符类型而memcpy可以复制任意类型 2.所需参数不同strcpy只需要目标空间和源空间而memcpy在次之上还需要源空间总大小 3.用途不同字符类的复制用strcpy其他类型的复制使用memcpy 3.memcpy的模拟实现
我们写的这个模拟实现的memcpy是不能实现重叠空间的拷贝的
#include stdio.h
#include assert.hvoid* My_memcpy(void* det, const void* src, size_t num)
{assert(detsrc);void* p det;while(num--){*(char*)det *(char*)src;det (char*)det 1;src (char*)src 1; }return p;
} 为什么不使用(char*)src(char*)det这种写法,因为这种写法有点问题有些编译器是不支持这样写的被(char*)强转了就是一个临时的变量对一个临时的变量进行操作是有问题的
用自定义函数My_memcpy进行重复空间的拷贝
#include stdio.h
#include assert.hvoid* My_memcpy(void* det, const void* src, size_t num)
{assert(det src);void* p det;while (num--){*(char*)det *(char*)src;det (char*)det 1;src (char*)src 1;}return p;
}
void test()
{int a[] { 1,2,3,4,5,6,7,8,9,10 };//int b[20] { 0 };My_memcpy(a 2, a, 28);int i 0;for (i 0; i 10; i){printf(%d , a[i]);}
}
int main()
{test();return 0;
}
运行结果 由上图知第三第四元素地址被第一第二元素地址覆盖了后面拿第三第四元素内容和第一第二元素一样后面的地址跟前面的同理就会出现如图这样的结果
tips
上面说了memcpy用于单独的两个空间重叠的内存也能实现但是C中规定它只能用于单独的两个空间那重叠内存的拷贝应该用什么函数 - memmove
十四. memmove函数
1.memmove的定义
void *memmove( void *dest, const void *src, size_t count );
负责拷贝重复空间中的数据
-1. void* destination 目标空间
-2. void* source 源空间
-3. size_t num 需要拷贝的字节数
它的目标空间和源空间是同一个空间
2.memmove的使用
#include stdio.h
#include string.hint main()
{int a[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};memmove(a 2, a, 20);int i 0;for(i 0; i 10; i){printf(%d , a[i]);}return 0;
}运行结果 3.memmove的模拟实现
#include stdio.h
#include assert.hvoid* My_memmove(void* det, const void* src, size_t num)
{assert(detsrc);void* p det;if (det src){while (num--){*(char*)det *(char*)src;det (char*)det 1;src (char*)src 1;}}else{while (num--){*((char*)det num) *((char*)src num);}}return p;
}
int main()
{int a[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };My_memmove(a 1, a 2, 20);int i 0;for (i 0; i 10; i){printf(%d , a[i]);}return 0;
}
运行结果