[c/c++] programming之路(22)、字符串(三)——字符串封装
项目结构
头文件.h
#include<stdio.h> #include<stdlib.h> #include<string.h> //字符串封装,需要库函数 //不需要库函数 struct CString { char *p;//保存字符串首地址 int real_len;//实际长度 }; typedef struct CString mystring;//简写 //字符串:初始化,打印,删除(字符,字符串) //查找(字符,字符串) //修改字符串,字符、字符串替换 //尾部增加,任意位置增加(字符,字符串) void init(mystring *string);//原封不动初始化 void init_len(mystring *string, int length);//开辟长度,内存清零 void init_string(mystring *string, char *copystring);//初始化并拷贝字符串 void printf_string(mystring *string);//打印 void back_addchar(mystring *string,char ch);//增加字符 void back_addstring(mystring *string,char *str);//增加字符串 void run(mystring *string);//执行指令 char * find_firstchar(mystring *string, char ch);//返回第一个找到的字符的地址 char * find_firststring(mystring *string, char *str);//返回第一个找到的字符串的地址 int delete_char(mystring *string,const char ch);//删除第一个找到的字符 int delete_string(mystring *string,char * const str);//删除第一个找到的字符串,const在*右边表明,指针不可修改 void add_char(mystring *string,char ch,char *pos);//任意位置增加字符 void add_string(mystring *string, char *str, char *pos);//任意位置增加字符串 void change_firstchar(mystring *string,const char oldchar,const char newchar);//改变字符 void change_firststring(mystring *string, char * const oldstring, char * const newstring);//改变字符串
字符串.c
#define _CRT_SECURE_NO_WARNINGS #include"字符串.h" int mystrlen(char *p) { if (p == NULL) return -1; int length = 0; while (*p) { length++; p++; } return length; } char *mystrcpy(char *dst, const char *src) {//const限定不被意外修改 if (dst == NULL || src == NULL) return NULL; char *dst_copy = dst;//保留地址 while (*src) { *dst = *src;//赋值字符 src++; dst++; } *dst = '\0'; return dst_copy;//返回原地址 } char *mystrcat(char *dst, const char *src) { if (dst == NULL || src == NULL) return NULL; char *dst_copy = dst; while (*dst) { dst++; } while (*src) { *dst = *src; dst++; src++; } *dst = '\0'; return dst_copy; } char *mystrchr(const char *dst, char ch) { if (dst == NULL) return NULL; while (*dst) { if (*dst == ch) return dst;//找到返回地址 dst++; } return NULL; } char *mystrstr(const char *const dst, const char *const findstr) { if (dst == NULL || findstr == NULL) return NULL; char *p = NULL;//保存找到的地址 char *dst_copy = dst; while (*dst_copy) { int flag = 1;//假定相等 char *findstr_copy = findstr;//因为每次循环,findstr都要重新开始,所以要在循环内部定义 char *now_dstcopy = dst_copy; while (*findstr_copy) { if (*now_dstcopy) {//当dst到了末尾‘\0’时就退出 if (*findstr_copy != *now_dstcopy)//只要有一个不等,整个字符串就不等 flag = 0;//代表不等 now_dstcopy++; findstr_copy++; } else {//findstr尚未遍历完,dst却已经遇到'\0'了 flag = 0; break; } } if (flag == 1) { p = dst_copy;//当前位置 return p; } dst_copy++; } return NULL; } //以上为自己封装的函数 void init(mystring *string) { string->p = NULL; string->real_len = 0;//初始化结构体字符串 } void init_len(mystring *string, int length) { //string->p=(char *)malloc(sizeof(char)*length);//分配内存 string->p = (char *)calloc(length, sizeof(char));//分配内存并清零 string->real_len = length; } void init_string(mystring *string, char *copystring) { //strlen函数是不包括‘\0’,sizeof才包括‘\0’的长度 int length = mystrlen(copystring);//获取字符串长度 string->p = (char *)calloc(length + 1, sizeof(char)); mystrcpy(string->p, copystring);//拷贝字符串(右拷贝到左) string->real_len = length + 1;//设置长度 } void printf_string(mystring *string) { printf("string=%s\n", string->p); } void back_addchar(mystring *string, char ch) {//尾部增加字符 if (strlen(string->p) + 1 == string->real_len)//意味着满了 { //重新分配内存 string->p = realloc(string->p, string->real_len + 1); string->real_len += 1; string->p[string->real_len - 2] = ch; string->p[string->real_len - 1] = '\0'; } else { int now_len = strlen(string->p);//求出当前长度 string->p[now_len] = ch; string->p[now_len + 1] = '\0'; } } void back_addstring(mystring *string, char *str) { int now_len = mystrlen(string->p);//获取当前长度 int add_len = mystrlen(str);//要增加的长度 if (now_len + add_len + 1 > string->real_len)//判定是否越界 { int need_len = now_len + add_len + 1 - string->real_len; //printf("%d", need_len); string->p = realloc(string->p, string->real_len + need_len);//增加字符串长度 //strcat(string->p, str); mystrcat(string->p, str);//拷贝字符串 string->real_len += need_len;//增加长度 } else mystrcat(string->p, str); } void run(mystring *string) { system(string->p);//执行指令 } char * find_firstchar(mystring *string, char ch) { //char *p = strchr(string->p, ch); char *p = mystrchr(string->p, ch);//查找某串在另一个串的位置 return p; } char * find_firststring(mystring *string, char *str) { //char *pres = strstr(string->p,str); char *pres = mystrstr(string->p, str); return pres;//返回地址 } int delete_char(mystring *string, const char ch) { char *p = mystrchr(string->p, ch);//查找字符 if (p==NULL) return 0; else { char *pnext = p + 1; //删除一个字符,整体向前移动 while (*pnext) { *p = *pnext; p++; pnext++; } *p = '\0';//字符串一定要有结尾 return 1; } } int delete_string(mystring *string, char * const str) { char *pres = mystrstr(string->p, str);//查找字符串 if (pres == NULL) return 0; else { int len = mystrlen(str);//求删除字符串的长度 char *pnext = pres + len;//下一个字符 while (*pnext) { *pres = *pnext; pres++; pnext++; } *pres = '\0'; return 1; } } void add_char(mystring *string, char ch, char *pos) { if (pos == NULL || string == NULL) return; int now_len = strlen(string->p);//求出当前长度 int move_len = mystrlen(pos);//要移动的长度 if (strlen(string->p) + 1 == string->real_len)//意味着满了 { //重新分配内存 string->p = realloc(string->p, string->real_len + 1); string->real_len += 1; for (int i = now_len; i >now_len - move_len; i--) { string->p[i] = string->p[i - 1]; } string->p[now_len - move_len] = ch; string->p[now_len + 1] = '\0'; } else { for (int i = now_len; i >now_len-move_len; i--) { string->p[i] = string->p[i - 1];//轮询 } string->p[now_len - move_len] = ch;//插入 string->p[now_len +1] = '\0';//结尾 } } void add_string(mystring *string, char *str, char *pos) { if (pos == NULL || string == NULL) return; int now_len = mystrlen(string->p);//获取当前长度 int add_len = mystrlen(str);//要增加的长度 if (now_len + add_len + 1 > string->real_len)//判定是否越界 { int need_len = now_len + add_len + 1 - string->real_len; //printf("%d", need_len); string->p = realloc(string->p, string->real_len + need_len);//增加字符串长度 string->real_len += need_len;//增加长度 //移动,拷贝 int now_len = strlen(string->p);//求出当前长度 int move_len = mystrlen(pos);//要移动的长度 int insert_len = strlen(str);//插入的长度 for (int i = now_len; i >= now_len-move_len; i--) { string->p[i+ insert_len] = string->p[i];//字符移动 } for (int j = 0; j < insert_len; j++) { string->p[now_len - move_len + j] = str[j];//赋值拷贝 } } else { int now_len = strlen(string->p);//求出当前长度 int move_len = mystrlen(pos);//要移动的长度 int insert_len = strlen(str);//插入的长度 for (int i = now_len; i >= now_len - move_len; i--) { string->p[i + insert_len] = string->p[i];//字符移动 } for (int j = 0; j < insert_len; j++) { string->p[now_len - move_len + j] = str[j];//赋值拷贝 } mystrcat(string->p, str); } } void change_firstchar(mystring *string, const char oldchar, const char newchar) { char *pstr = string->p; while (*pstr) { if (*pstr == oldchar)//查找 { *pstr = newchar;//赋值 return; } pstr++; } } void change_firststring(mystring *string, char * const oldstring, char * const newstring) { char *pfind = find_firststring(string, oldstring);//找到位置 if (pfind!=NULL) { delete_string(string, oldstring);//删除 add_string(string, newstring, pfind);//插入 } }
main函数(进行测试)
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include"字符串.h" void main() { mystring string1; init_string(&string1,"note"); printf_string(&string1); //back_addchar(&string1, 't'); back_addstring(&string1, "pad_notepad"); printf_string(&string1); //change_firststring(&string1,"notepad","123456789");//替换第一次出现的notepad //替换所有的notepad while (find_firststring(&string1,"notepad")) { change_firststring(&string1, "notepad", "123456789"); } /*delete_char(&string1,'e'); delete_string(&string1,"pad");*/ /*char *p= find_firstchar(&string1, 't'); if (p != NULL) add_string(&string1, "12345", p);*/ /*char *strp = find_firstchar(&string1, 'a'); *strp = 'A';*/ /*char *strp = find_firststring(&string1, "ada"); if(strp!=NULL) *strp = 'X';*/ printf_string(&string1); //run(&string1); system("pause"); }
PS:这是迄今学习C++最难最痛苦的一次编程(学指针都没那么痛苦),后面的几个函数并未看懂。。。希望以后回头再看的时候能够有所长进,这段代码的视频不到2小时,看了好几天,头都晕了还看不懂,智商真的很堪忧呀