不使用库函数strcat(),自行编程实现str_append()功能

本文介绍了一种不依赖于标准库函数的方法来实现字符串的拼接。通过自定义的str_append()函数,演示了如何将两个字符串连接成一个新的字符串。

不使用库函数strcat(),自行编程实现str_append()功能:已知两个字符串,将这两个字符串拼接起来作为返回值。例如函数输入参数为“Hello”和"World",那么返回值就是"HelloWorld";

#include <stdio.h>
#include <string.h>
char str_append(char s[],char t[])
{
	int i,j;
	i=j=0;
	while(s[i]!='\0')
			i++;
	   while((s[i++]=t[j++])!='\0');
	
}
 main()
 {
 	char s[]="hello";
 	char t[]="world";
 	str_append(s,t);
 	printf("%s",s);
 }


 


 

一、项目概述 目标:设计并实现字符串操作类hstring,实现自定义字符串的增、删、改、查等核心功能,通过缓 冲区机制减少内存频繁分配/释放的开销,全面考察类设计、运算符重载及算法实现能力。 核心特性: *依赖C++标准库string类,完全自主实现底层逻辑; *基于缓冲区(Buffer)的内存管理策略; *支持运算符重载(、、)及自定义字符串操作; *严格限制内存分配次数(关键操作最多new一次); 二、核心需求与功能设计 1. 缓冲区(Buffer)设计 ‘目的:减少new/delete高频调用带来的性能损耗; “实现要求: °内置固定大小初始缓冲区(如默认大小INIT_BUFF_SIZE=128) °数据存储优先使用缓冲区,仅当内容超过缓冲区大小时触发动态内存分配 。new操作前必须进行容量检查:if (需要的容量>缓冲区剩余空间)才执行new 2.运算符重载与核心操作 (1)加法运算符+重载 "功能:字符串拼接,实现hstring + hstring或hstring + const chan* ‘示例: hstring s1("123456789"), s2("abc"); hstring result = s1 + s2; // 结果为 "123456789abc" “实现约束: °最多执行**1次new**(仅当拼接后总长度超过缓冲区时触发) °优先尝试在现有缓冲区或目标缓冲区中直接拼接,足时分配新内存 (2)减法运算符-重载 *功能:子串删除,从原字符串中移除首次出现的目标子串 ‘示例: hstring s("123456789"); hstring result = s - "456"; // 结果为 "123789" ‘实现约束: ‘**禁止使用new**,直接在原字符串缓冲区或临时缓冲区中操作 ‘未找到子串时抛出错误提示(如std::cout<"子串未找到”<<std::end1;) (3)修改操作(自定义函数) *功能:指定位置子串替换 “示例: hstring s("123456789"); s.replace(2, "34", "abc"); // 从位置 2 开始,将 "34" 替换为 "abc",结果为 "12abc56789" “实现约束: ‘最多执行**1次new**(仅当替换后总长度变化超过缓冲区容量时触发); ‘未找到目标子串时输出错误提示; (4)查找操作(自定义函数) *功能:定位子串首次出现的位置 “示例: hstring s("123456"); int pos = s.find("34"); // 返回位置2 (从 0 或 1 开始索引需统一规范) ‘实现约束: ‘**禁止使用new**,纯算法实现(如 KMP或暴力匹配) ‘未找到子串时返回特殊值(如-1)并输出错误提示 (5)赋值运算符=重载 功能:支持int类型转换为hstring “示例: hstring s; s = “12345 ; // s 内容为"12345" ‘实现约束: 最多执行**1次new**(根据整数转换后的字符串长度分配内存) 处理正负整数及0的特殊情况 3. 禁止与允许的操作 ‘禁止使用库函数strlen、strcpy、strcat、find(C++ 标准库方法)等 ‘允许使用函数:(memcpy)(用于缓冲区数据复制)、memset(缓冲区初始化) 三、实现关键点 缓冲区架构: class hstring { private: char* buffer; //动态缓冲区(含初始缓冲区) size_t buffer_size;//缓冲区总容量 size_t data_length;//实际存储字符串长度 static const size_t INIT_BUFF_SIZE = 128; // 初始缓冲区大小 } 内存分配策略: *初始化时分配INIT_BUFF_SIZE大小的缓冲区 *扩容时按buffer_size*2动态扩展(避免频繁小额分配) 错误处理: “所有涉及索引/子串查找的操作,需先检查输入合法性(如索引越界、子串长度为0) ‘未找到目标时统一通过标准错误流输出提示信息(如cerr) 四、测试要求 单元测试覆盖: "每个功能模块(增、删、改、查、赋值》需独立测试 *边界条件测试:空字符串、单字符操作、缓冲区满临界值等 *异常场景测试:删除未存在的子串、修改越界位置、查找空字符串等 输出规范: “未找到目标子串时,必须输出明确错误信息(如[ERROR]子串"xxx”未找到!) 五、项目考察点 类设计能力:缓冲区管理、数据封装、运算符重载; 指针与内存操作:动态内存分配策略、缓冲区安全操作(避免越界); 算法思维:子串查找(暴力匹配/KMP)、字符串拼接与删除的实现; 工程规范:代码可读性、注释完整性、错误处理机制; 已经完成 #include #include class hstring { unsigned int uselen; unsigned int usesize; char* cstr; public: hstring() ; const char* c_str() const;//使用接口访问 void set_string(const char* input); void append(const hstring& other); int find_string(const char* find); int sub_string(const char* sub); void modify_string(char* position, char* source, char* replace); }; hstring::hstring() :uselen(0), usesize(128), cstr(new char[usesize]) {//默认构造函数进行初始化 cstr[0] = ‘\0’; }; const char* hstring::c_str() const {//接口调用函数 return cstr; } void hstring::set_string(const char* input) { int i = 0; while (input[uselen] != ‘\0’)++uselen;//读取字符串长度 //printf(“%d\n”, uselen); while (uselen > usesize - 1) { usesize = 2; } char new_cstr = new char[usesize]; while (input[i] != ‘\0’ && i < usesize - 1) { new_cstr[i] = input[i]; ++i; } new_cstr[i] = ‘\0’; if (cstr != nullptr) { delete[]cstr; } cstr = new_cstr; } void hstring::append(const hstring& other) { int new_len = this->uselen + other.uselen; int new_size = usesize; if (new_len > usesize - 1) { usesize*=2; } char* new_str = new char[new_len]; int i = 0; for (i = 0; i<uselen; ++i) { new_str[i] = cstr[i]; } for (i = 0; i < other.uselen; ++i) { new_str[uselen + i] = other.cstr[i]; } new_str[new_len] = ‘\0’; delete[]cstr; cstr = new_str; uselen = new_len; usesize = new_size; } int hstring::find_string(const char* find) { if (cstr == nullptr) { printf(“源字符串为空指针\n”); return -1; } if (find == nullptr) { printf(“输入字符串为空指针\n”); return -1; } int main_len = uselen; int find_len = 0; while (find[find_len] != ‘\0’)++find_len; if (find_len == 0) { printf(“为空字符串,默认匹配位置为0\n”); return 0; } if (main_len < find_len) { printf(“主字符串小于子字符串大小\n”); return -1; } for (int i = 0; i < main_len - find_len; ++i) { int j = 0; while(j < find_len && cstr[i + j] == find[j]){ ++j; } if (j == find_len) printf(“找到字符串,位置:%d”,i); return i; } printf(“未找到字符串”); return -1; } int hstring::sub_string(const char* sub) { } //第一种简单直观的方法: int main() { hstring s; s.set_string(“123456789”); printf(“%s\n”, s.c_str());//使用接口访问 hstring s1; s1.set_string(“abc”); s.append(s1); printf(“%s\n”, s.c_str()); hstring s3; s3.set_string(“456”); s.find_string(s3.c_str()); printf(“%s\n”, s3.c_str()); //std::cout << s << std::endl; //std::cout << uselen << std::endl; } 这是我已经写好的,现在就是就用C风格,并且用hstring构造函数和拷贝构造函数、重载运算符的用法,string库就自己手搓实现再补充一点,能用禁止使用库函数:strlen、strcpy、find、strcat,做一个手搓的实现,让我了解底层 请注意内存大小只给128,能分配新内存
08-14
#include #include class hstring { unsigned int uselen; unsigned int usesize; char* cstr; public: hstring() ; const char* c_str() const;//使用接口访问 void set_string(const char* input); void append(const hstring& other); int find_string(const char* find); int sub_string(const char* sub); void modify_string(char* position, char* source, char* replace); }; hstring::hstring() :uselen(0), usesize(128), cstr(new char[usesize]) {//默认构造函数进行初始化 cstr[0] = ‘\0’; }; const char* hstring::c_str() const {//接口调用函数 return cstr; } void hstring::set_string(const char* input) { int i = 0; while (input[uselen] != ‘\0’)++uselen;//读取字符串长度 //printf(“%d\n”, uselen); while (uselen > usesize - 1) { usesize = 2; } char new_cstr = new char[usesize]; while (input[i] != ‘\0’ && i < usesize - 1) { new_cstr[i] = input[i]; ++i; } new_cstr[i] = ‘\0’; if (cstr != nullptr) { delete[]cstr; } cstr = new_cstr; } void hstring::append(const hstring& other) { int new_len = this->uselen + other.uselen; int new_size = usesize; if (new_len > usesize - 1) { usesize*=2; } char* new_str = new char[new_len]; int i = 0; for (i = 0; i<uselen; ++i) { new_str[i] = cstr[i]; } for (i = 0; i < other.uselen; ++i) { new_str[uselen + i] = other.cstr[i]; } new_str[new_len] = ‘\0’; delete[]cstr; cstr = new_str; uselen = new_len; usesize = new_size; } int hstring::find_string(const char* find) { if (cstr == nullptr) { printf(“源字符串为空指针\n”); return -1; } if (find == nullptr) { printf(“输入字符串为空指针\n”); return -1; } int main_len = uselen; int find_len = 0; while (find[find_len] != ‘\0’)++find_len; if (find_len == 0) { printf(“为空字符串,默认匹配位置为0\n”); return 0; } if (main_len < find_len) { printf(“主字符串小于子字符串大小\n”); return -1; } for (int i = 0; i < main_len - find_len; ++i) { int j = 0; while(j < find_len && cstr[i + j] == find[j]){ ++j; } if (j == find_len) printf(“找到字符串,位置:%d”,i); return i; } printf(“未找到字符串”); return -1; } int hstring::sub_string(const char* sub) { } //第一种简单直观的方法: int main() { hstring s; s.set_string(“123456789”); printf(“%s\n”, s.c_str());//使用接口访问 hstring s1; s1.set_string(“abc”); s.append(s1); printf(“%s\n”, s.c_str()); hstring s3; s3.set_string(“456”); s.find_string(s3.c_str()); printf(“%s\n”, s3.c_str()); //std::cout << s << std::endl; //std::cout << uselen << std::endl; } 您是一位C++老师,对学生进行Hstring的一个测试现在我已经写了这么多,但是减法还会, 这是我已经写好的,现在就是就用C风格,并且用hstring构造函数和拷贝构造函数、重载运算符的用法,string库就自己手搓实现再补充一点,能用禁止使用库函数:strlen、strcpy、find、strcat,做一个手搓的实现,让我了解底层 前面的代码里,写的内容也是根据要求写的,是已经确定的了条件的,用改,也受减法的要求约束,但是我现在减法模块还没写,会写,实现的约束如下 实现约束 这是减法模块单个实现时的一个要求: **禁止使用 new**,直接在原字符串缓冲区或临时缓冲区中操作未找到子串时抛出错误提示(如std::cout<<"子串未找到"<<std::endl;)
最新发布
08-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值