项目结构

头文件.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. redis操作封装类

    class Redis {     // 默认配置名称(使用load_config加载) private $_default_config_path = 'package/cache/redis'; ...

  2. Linux 的基本操作(系统的安装)

    操作系统的安装: 操作系统的安装 这次安装系统也是基于CentOS的安装.把光盘插入光驱,设置bios光驱启动.进入光盘的欢迎界面. 其中有两个选项,可以直接按回车,也可以在当前界面下输入 linux ...

  3. html 中a标签的问题(无反应,跳转,调用方法)

    让超链接点击后不跳转,可以用href = "#",但是这个#就会锚点到页面最上边     点击链接后不跳转可以设置成     1.<a href="javascri ...

  4. 剑指offer——python【第30题】连续子数组的最大和

    题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...

  5. python--列表,元组,字符串互相转换

    列表,元组和字符串python中有三个内建函数:,他们之间的互相转换使用三个函数,str(),tuple()和list(),具体示例如下所示 >>> s = "xxxxx& ...

  6. ArcPy中mapping常见函数及用法1

    arcpy的mapping模块常见属性方法总结1.如何获取当前地图文档: 方式:mxd = mapping.MapDocument("CURRTENT")引用本地或者网络文档(ar ...

  7. 并行开发-Paraller

    并行开发的概念 并行开发要做的事情就是将任务分摊给硬件线程去并行执行来达到负载和加速,传统的代码都是串行的,就一个主线程,当我们为了实现加速而开了很多工作线程,这些工作线程就是软件线程 Paralle ...

  8. Objective-C语法之代码块(block)的使用 (转载)

    代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定 ...

  9. selenium 淘宝登入反爬虫解决方案(亲测有效)

    前言 目前在对淘宝进行数据爬取的时候都会碰到,登入时的滑块问题,无论是手动还是脚本都不成功.这里的很重要一个原因是很多的网站都对selenium做了反爬虫机制.接下来是笔者参考网上的网友们的方法亲自测 ...

  10. VUE中的v-show和v-if

    v-show="判断条件" 显示或隐藏 v-show占位置 v-if 隐藏(不占位置)