入门学习计算机第十七天—字符串函数使用和剖析
发布日期:2021-06-28 16:38:50
浏览次数:2
分类:技术文章
本文共 6767 字,大约阅读时间需要 22 分钟。
入门学习计算机第十七天—字符串函数使用和剖析
编译器:Microsoft Visual Studio 2019
前言:
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 或者 字符数组中,字符串常量适用于那些对它不做修改的字符串函数。字符函数介绍 :
strlen: 字符串长度
size_t strlen (const char* str)//typedef unsigned int size_t
- 字符串以’\0’作为结束标志,strlen函数返回的是在字符串中’\0’ 前面出现的字符个数。
- 参数指向的字符串必须要以’\0’结束。
- 注意函数的放回值为size_t ,是无符号的(易错)
int main(){ if (strlen("abc") - strlen("abcdef") > 0) { printf("hehe"); } else { printf("haha"); } return 0;}
输出的结果是 “hehe”
strlen 返回值的类型是无符号数,两个无符号数相减,得到的结果依然是无符号数不创建临时变量,求字符串长度
int my_strlen(char* a){ if (*a != 0) return 1 + my_strlen(a + 1); else return 0;}int main(){ char arr[] = "abcdef"; printf("%d\n", my_strlen(arr)); return 0;}
输出的结果是6。
strcpy 字符串拷贝
char* strcpy(char* destination ,const char* source);
- 原字符串以’\0’结束
- 会将字符串中的’\0’拷贝到目标空间
- 目标空间必须足够大,以确保能存放原字符串
- 目标空间必须可变
模拟实现strcpy
char* my_strcpy(char* dest, const char* src){ assert(dest != NULL); assert(src != NULL); char* ret = dest; //拷贝src指向的字符串到dest指向的空间,包含'\0' while (*dest++ = *src++) { ; } //返回目的空间的起始地址 return ret;}int main(){ char arr1[] = "abcdefghi"; char arr2[] = "bit"; my_strcpy(arr1, arr2); printf("%s\n", arr1); return 0;}
strcat 字符串追加
char* strcat (char* destnation, const char* source);
- 原字符串以’\0’结束
- 目标空间必须足够大,以确保能容纳原字符串的内容
- 目标空间必须可修改
- 字符串自己给字节追加?
模拟实现 strcat
char* my_strcat(char* dest, const char* src){ assert(dest); assert(src); char* ret = dest; //1.找到目的字符串的'\0' while (*dest != '\0') { dest++; } //2.追加 while (*dest++ = *src++) { ; } return ret;}int main(){ char arr1[50] = "hello"; char arr2[] = "world"; my_strcat(arr1, arr2); printf("%s\n", arr1); return 0;}
strcmp 字符串比较
int strcmp(const char *str1 , const char * str2)
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,返回0
- 第一个字符串小于第二个字符串,返回小于0的数字
int main(){ const char* p1 = "chen"; const char* p2 = "wen"; int rent = (strcmp(p1, p2)); printf("%d\n", rent); return 0;}
输出的值是 -1
模拟实现strcmp
int my_strcmp(const char* a1, const char* a2){ while (*a1 ==*a2) { if (*a1 == '\0') { return 0;//相等 } a1++; a2++; } if (*a1 > *a2) return 1;// else return -1;}int main(){ const char* p1 = "chen"; const char* p2 = "when"; printf("%d\n", my_strcmp(p1, p2)); return 0;}
strncpy 长度受限制的字符拷贝
char* strncpy(char* strDest, const* strSource , size_t count) //count 的单位是字节
- 拷贝num个字符从原字符串到目标空间
- 如果原字符串的长度小于num,则拷贝完原字符串之后,在目标的后边追加0,直至num个
int main(){ char arr1[10] = "abcdefgh"; char arr2[] = "hello bit"; strncpy(arr1, arr2, 5); printf("%s\n", arr1); return 0;}
输出的结果是
模拟实现strncpychar* my_strncpy(char* arr1, char* arr2, int count){ char* start = arr1; while (count && (*arr1++ = *arr2++)) { count--; } if (count) { while (--count) { *arr1++ = '\0'; } } return start;}int main(){ char arr1[10] = "ab"; char arr2[] = "hello bit"; my_strncpy(arr1, arr2, 10); printf("%s\n", arr1); return 0;}
strncat 长度受限制的字符追加
char* strncat(char* strDest, const char* strSource, size_t count)
int main(){ char arr1[30] = "hello\0XXXXXXX"; char arr2[] ="world"; strncat(arr1,arr2,3);//strncat会主动补\0 printf("%s\n",arr1);}模拟实现strncat
char* my_strncat(char* front, const char* back, size_t count){ char* start = front; while (*front++) { ; } front--; while (count--) { if (!(*front++ = *back++)) { return start; } } *front = '\0'; return start;}int main(){ char arr1[30] = "hello"; char arr2[]= "world"; my_strncat(arr1, arr2, 3);//strncat会主动补\0 printf("%s\n", arr1);}
strncmp 长度受限制的字符比较
int strncmp(const char* str1 , const char* str2 ,size_t num);
- 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。
int main(){ char arr1[30] = "hello"; char arr2[]= "helle"; int ret = strncmp(arr1, arr2, 4);//strncat会主动补\0 printf("%d\n",ret ); return 0;}
输出的结果是0
模拟实现strncmp
strstr 寻找子字符串
char* strstr(const char* string, const char * strCharSet)
int main(){ char* p1 = "abcdef"; char* p2 = "def"; char* ret = strstr(p1,p2); if(ret == NULL) { printf("子串不存在\n"); } else { printf("%s\n",ret); } return 0;}
模拟实现
char* my_strstr(const char* str1, const char* str2){ assert(str1); assert(str2); const char* s1 = str1; const char* s2 = str2; const char* cur = str1; if (*str2 == '\0') { return (char*)str1; } while (*cur) { s1 = cur; s2 = str2; while ((*s1!='\0') && (*s2 != '\0') && *s1 == *s2) { s1++; s2++; } if (*s2 == '\0') { return (char*)cur; } if (*s1 == '\0') { return NULL; } cur++; } return NULL;//找不到子串}int main(){ char arr1[30] = "abcdefgih"; char arr2[]= "defasdawrawra"; const char* len = my_strstr(arr1, arr2); printf("%s\n",len ); return 0;}
strtok 提取被符号分割的字符串
char* strtok(char* str ,const char* sep)
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串一个或者多个分隔符分割的标记
- strtok 函数找到了str中的下一个标记,并将其用\0结尾 ,返回一个指向这个标记的指针(注:strtok函数会改变被操作的字符串找到str中的下一个标记,所以使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改)
- strtok函数的第一个参数不为NULL,函数将找到str第一个标记,strtok函数将保存它在字符串中的位置
- strtok函数的第一个参数为NULL,函数将同一个字符串中被保存的位置开始,查找下一个标记
- 如果字符串不存在更多的标记,则返回NULL指针
函数的基本使用
int main(){ char arr[] = "abcd.ad.w@er"; const char* p = "@."; char* len = NULL; for (len = strtok(arr, p); len != NULL; len = strtok(NULL, p)) { printf("%s\n", len); } return 0;}strerror 错误信息函数 需要引头文件<errno.h>
char* strerror(int errnum);//返回错误码,所对应的错误信息
errno 是一个全局的错误码变量
当C语言的库函数在执行过程中,发生了错误,将会把对应的错误码,赋值到errno中 函数使用:打开text.txt文件int main(){ FILE* pf = fopen("text.txt", "r");//打开文件 if (pf == NULL) { printf("%s\n", strerror(errno)); } else { printf("open file success\n"); } return 0;}
当code文件夹下没有text.txt文件时:
没有该文件或者目录 当文件下有text.txt文件时字符转换:需要引头文件 <ctype.h>
int tolower(int c);//大写转小写 int toupper(int c);//小写转大写
int main(){ char arr = tolower("Q"); putchar(arr);}
输出的结果是q
将一个字符串全部打印成小写
int main(){ char arr[] = "I Am A Student"; int i = 0; while (arr[i]) { if (isupper(arr[i]))//判断是否为大写 { arr[i] = tolower(arr[i]); } i++; } printf("%s\n", arr); return 0;}
输出的结果为:
内存函数
memmove: 内存移动函数
void* memmove(void* destination ,const void* soure,size_t num);
- 和mencpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理
memcpy: 内存拷贝函数
void* memcpy(void* destination , const void* source, size_t num)
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置
- 这个函数在遇到’\0’的时候并不会停下来
- 如果source和destination有任何的重叠,复制的结果都是未定义的
int main(){ int arr1[] = { 1,2,3,4,5,6}; int arr2[] = { 0}; memcpy(arr2,arr1,6);}模拟实现memcpy函数:
void* my_memcpy(void* dest, const void* src, size_t num){ assert(dest); assert(src); void* ret = dest; while(num--) { *(char*)dest = *(char*)src; ++(char*)dest; ++(char*)src; } return ret;}int main(){ int arr1[] = { 1,2,3,4,5,6 }; int arr2[10] = { 0 }; my_memcpy(arr2, arr1,sizeof(arr1)); return 0;}
计算机知识/代码知识(零碎)
阅读文档的时候:
NULL - 空指针 NUL / Null - ‘\0’转载地址:https://blog.csdn.net/xiaotangyu7dong/article/details/116559906 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月04日 11时22分58秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
SecureCRT连接不上虚拟机
2019-04-28
从100万个数中找出最大的前100个数-最小堆、分块
2019-04-28
并发下的ArrayList、HashMap
2019-04-28
仿牛客社区项目2.2登录模块——开发注册功能
2019-04-28
仿牛客社区项目2.3登录模块——会话管理Cookie、Session
2019-04-28
仿牛客社区项目2.4登录模块——生成验证码
2019-04-28
JDK-JRE-JVM关系、Java语言跨平台
2019-04-28
仿牛客社区项目2.5登录模块———登录退出功能
2019-04-28
仿牛客社区项目3.2——发布帖子(异步通信技术AJAX)
2019-04-28
仿牛客社区项目3.3——帖子详情(普通功能)
2019-04-28
仿牛客社区项目3.5——显示评论(普通功能,Controller层帖子-评论-回复)
2019-04-28
仿牛客社区项目3.6——增加评论,同时更新评论数【事务】
2019-04-28
[golang]-go中字符串格式化与fmt包简介
2019-04-28
[Leet-go]-复杂链表的复制
2019-04-28
五分钟上手ECharts图形报表
2019-04-28
权限控制之Spirng Security框架
2019-04-28
Excel处理:Apache POI
2019-04-28