项目结构

头文件.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 -;
int length = ;
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 = ;//假定相等
char *findstr_copy = findstr;//因为每次循环,findstr都要重新开始,所以要在循环内部定义
char *now_dstcopy = dst_copy;
while (*findstr_copy)
{
if (*now_dstcopy) {//当dst到了末尾‘\0’时就退出
if (*findstr_copy != *now_dstcopy)//只要有一个不等,整个字符串就不等
flag = ;//代表不等
now_dstcopy++;
findstr_copy++;
}
else {//findstr尚未遍历完,dst却已经遇到'\0'了
flag = ;
break;
}
}
if (flag == ) {
p = dst_copy;//当前位置
return p;
}
dst_copy++;
}
return NULL; } //以上为自己封装的函数 void init(mystring *string) {
string->p = NULL;
string->real_len = ;//初始化结构体字符串
}
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 + , sizeof(char));
mystrcpy(string->p, copystring);//拷贝字符串(右拷贝到左)
string->real_len = length + ;//设置长度
}
void printf_string(mystring *string) {
printf("string=%s\n", string->p);
}
void back_addchar(mystring *string, char ch) {//尾部增加字符
if (strlen(string->p) + == string->real_len)//意味着满了
{
//重新分配内存
string->p = realloc(string->p, string->real_len + );
string->real_len += ;
string->p[string->real_len - ] = ch;
string->p[string->real_len - ] = '\0';
}
else
{
int now_len = strlen(string->p);//求出当前长度
string->p[now_len] = ch;
string->p[now_len + ] = '\0';
}
}
void back_addstring(mystring *string, char *str) {
int now_len = mystrlen(string->p);//获取当前长度
int add_len = mystrlen(str);//要增加的长度
if (now_len + add_len + > string->real_len)//判定是否越界
{
int need_len = now_len + add_len + - 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 ;
else
{
char *pnext = p + ;
//删除一个字符,整体向前移动
while (*pnext)
{
*p = *pnext;
p++;
pnext++;
}
*p = '\0';//字符串一定要有结尾
return ;
}
} int delete_string(mystring *string, char * const str) {
char *pres = mystrstr(string->p, str);//查找字符串
if (pres == NULL)
return ;
else
{
int len = mystrlen(str);//求删除字符串的长度
char *pnext = pres + len;//下一个字符
while (*pnext)
{
*pres = *pnext;
pres++;
pnext++;
}
*pres = '\0';
return ;
}
} 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) + == string->real_len)//意味着满了
{
//重新分配内存
string->p = realloc(string->p, string->real_len + );
string->real_len += ; for (int i = now_len; i >now_len - move_len; i--)
{
string->p[i] = string->p[i - ];
}
string->p[now_len - move_len] = ch;
string->p[now_len + ] = '\0';
}
else
{
for (int i = now_len; i >now_len-move_len; i--)
{
string->p[i] = string->p[i - ];//轮询
}
string->p[now_len - move_len] = ch;//插入
string->p[now_len +] = '\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 + > string->real_len)//判定是否越界
{
int need_len = now_len + add_len + - 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 = ; 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 = ; 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", "");
}
/*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小时,看了好几天,头都晕了还看不懂,智商真的很堪忧呀

[c/c++] programming之路(22)、字符串(三)——字符串封装的更多相关文章

  1. 《程序设计语言——实践之路(英文第三版)》【PDF】下载

    <程序设计语言--实践之路(英文第三版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382234 内容简介 <程序设计语 ...

  2. Python进阶之路---1.5python数据类型-字符串

    字符串 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; ...

  3. iOS开发-OC语言 (三)字符串

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 24.0px "PingFang SC" } p ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(三) 补充 hector_slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(三) indigo rplidar rviz slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. python之路-----MySql操作三

    mysql 概述 一.主要内容: 视图 create view name (select * from user where id>5); 触发器 函数 存储过程 索引 二.各模块详细说明 1. ...

  7. Python之路-基础数据类型之字符串

    字符串类型 字符串是不可变的数据类型 索引(下标) 我们在日常生活中会遇到很多类似的情况,例如吃饭排队叫号,在学校时会有学号,工作时会有工号,这些就是一种能保证唯一准确的手段,在计算机中也是一样,它就 ...

  8. Programming Python 3rd Edition 第三版 pdf chm下载

    Programming Python 作为一款经典系列书籍 非常的耐看 建议有志于学习python的童鞋好好看看 网上 Programming Python第四版的 pdf 下载非常容易 也就是最新的 ...

  9. Python核心技术与实战——三|字符串

    一.字符串基础 Python的字符串支持单引号('').双引号("")和三引号之中('''....'''和"""...""&quo ...

  10. Python专题三字符串的基础知识

    Python专题三字符串的基础知识 在Python中最重要的数据类型包括字符串.列表.元组和字典等.该篇主要讲述Python的字符串基础知识. 一.字符串基础 字符串指一有序的字符序列集合,用单引号. ...

随机推荐

  1. cc攻击和ddos攻击

    DoS攻击.CC攻击的攻击方式和防御方法 DDoS介绍 DDoS是英文Distributed Denial of Service的缩写,意即“分布式拒绝服务”,那么什么又是拒绝服务(Denial of ...

  2. HyperLogLog 算法的原理讲解以及 Redis 是如何应用它的

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  3. laravel 5.4 导出excel表格

    1.在laravel根目录下面找到一个composer.json文件 打开并在require下面加上一句话,如图所示: 注:以后这个excel的版本号可能还会修改 2.执行 composer inst ...

  4. macOS Sierra上面的php开发环境安装

    本文参考资料: 启动apache时,解决  How to Fix AH00558 and AH00557 httpd apr_sockaddr_info_get() Error Message     ...

  5. vue2.0 --- vuex (一)

    之前做vue项目中没有使用vuex  一直使用vue-router 组件.路由一直的转换,烦不胜烦 今天研究一下vuex vuex是什么: vuex是专门为vue.js应用程序开发的状态管理模式. 解 ...

  6. js中级小知识3

    函数: 函数在调用的时候,会形成一个私有作用域,内部的变量不会被外面访问,这种保护机制叫闭包.这就意味着函数调用完毕,这个函数形成的栈内存会被销毁. 有些时候我们不希望他被销毁. 函数归属谁跟它在哪调 ...

  7. MySQL查看、创建和删除索引的方法

    本文实例讲述了MySQL查看.创建和删除索引的方法.分享给大家供大家参考.具体如下: 1.索引作用 在索引列上,除了上面提到的有序查找之外,数据库利用各种各样的快速定位技术,能够大大提高查询效率.特别 ...

  8. Golang中mac地址+时间戳加入rand.Seed()产生随机数

    记录一下用mac地址+local时间作为seed来产生随机数 // 首先记录一下rand.Seed()怎么用 // 官方说明,传入int64数据为Seed func (r *Rand) Seed(se ...

  9. Redis实战经验及使用场景

    随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...

  10. ionic3.x版本开发问题记录---使用Image Resizer打包报错问题

    按照官方文档安装和使用,最后在打包的时候报错 /platforms/android/src/info/protonet/imageresizer/ImageResizer.java:12: error ...