C++手撕strcpy、strncpy、strcat、strncat、memcpy、memset、memmove函数

7 篇文章 3 订阅
本文档展示了如何实现C++中的字符串和内存操作函数,包括WeStrcpy、WeStrncpy、WeStrcat、WeStrncat、WeMemcpy、WeMemset和WeMemmove。每个函数都有详细的实现逻辑,考虑了边界条件和内存重叠情况。同时,提供了TestMain.cpp用于测试这些函数的正确性。
摘要由CSDN通过智能技术生成

CommonFunction.h

#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <string>


char* WeStrcpy(char* dest_buf, const char* src_buf);
char* WeStrncpy(char* dest_buf, const char* src_buf, int size);
char* WeStrcat(char* dest_buf, const char* src_buf);
char* WeStrncat(char* dest_buf, const char* src_buf, int size);
void* WeMemcpy(void* dest_buf, const void* src_buf, int size);
void* WeMemset(void* dest_buf, int value, int size);
void* WeMemmove(void* dest_buf, const void* src_buf, int size);

CommonFunction.cpp

#include "CommonFunction.h"


char* WeStrcpy(char* dest_buf, const char* src_buf)
{
	if (dest_buf == nullptr || src_buf == nullptr) { // 空指针判断
		throw "Invalid parameter";
	}
	char* dest_buf_cpy = dest_buf;                   // 记录好指针头部不变
	while (*src_buf != '\0') {
		*(dest_buf_cpy++) = *(src_buf++);
	}
	return dest_buf;
}

char* WeStrncpy(char* dest_buf, const char* src_buf, int size)
{
	assert(dest_buf != nullptr && src_buf != nullptr);
	assert(size >= 0);
	char* dest_buf_cpy = dest_buf;                   // 记录好指针头部不变
	while (( * src_buf != '\0')&& size > 0) {
		*(dest_buf_cpy++) = *(src_buf++);
		size--;
	}
	return dest_buf;
}

char* WeStrcat(char* dest_buf, const char* src_buf)
{
	assert(dest_buf != nullptr && src_buf != nullptr);
	int offset = strlen(dest_buf);                   // strlen 计算有效字符的长度
	char* dest_buf_cpy = dest_buf + offset;          // 记录好指针是目的指针+目的有效字符的长度开始
	while (*src_buf != '\0') {
		*(dest_buf_cpy++) = *(src_buf++);
	}
	return dest_buf;
}


char* WeStrncat(char* dest_buf, const char* src_buf, int size)
{
	assert(dest_buf != nullptr && src_buf != nullptr);
	assert(size >= 0);
	int offset = strlen(dest_buf);                   // strlen 计算有效字符的长度
	char* dest_buf_cpy = dest_buf + offset;          // 记录好指针是目的指针+目的有效字符的长度开始
	while ((*src_buf != '\0') && size > 0) {
		*(dest_buf_cpy++) = *(src_buf++);
		size--;
	}
	return dest_buf;
}


void* WeMemcpy(void* dest_buf, const void* src_buf, int size)
{
	assert(dest_buf != nullptr && src_buf != nullptr);
	assert(size >= 0);
	char* dest_buf_cpy = nullptr;
	char* src_buf_cpy = nullptr;
	if ((src_buf < dest_buf) && ((char*)src_buf + size > (char*)dest_buf)) { // 有重叠区域,考虑从后往前复制
		dest_buf_cpy = (char*)dest_buf + size - 1;
		src_buf_cpy = (char*)src_buf + size - 1;
		while (size > 0) {
			*(dest_buf_cpy--) = *(src_buf_cpy--);
			size--;
		}
	} else { // 没有重叠区域,从前往后拷贝
		dest_buf_cpy = (char*)dest_buf;
		src_buf_cpy = (char*)src_buf;
		while (size > 0) {
			*(dest_buf_cpy++) = *(src_buf_cpy++);
			size--;
		}
	}
	return dest_buf;
}


void* WeMemset(void* dest_buf, int value, int size)
{
	assert(dest_buf != nullptr);
	assert(size >= 0);
	char* dest_buf_cpy =static_cast<char*>(dest_buf);
	while (size > 0) {
		*(dest_buf_cpy++) = value;
		size--;
	}
	return dest_buf;
}


void* WeMemmove(void* dest_buf, const void* src_buf, int size)
{
	assert(dest_buf != nullptr && src_buf != nullptr);
	assert(size >= 0);
	char* dest_buf_cpy = (char*)dest_buf;
	char* src_buf_cpy = (char*)src_buf;
	if (src_buf_cpy < dest_buf_cpy && (src_buf_cpy + size) > dest_buf_cpy) { // 有重叠区域,考虑从后往前复制
		dest_buf_cpy = dest_buf_cpy + size - 1;
		src_buf_cpy = src_buf_cpy + size - 1;
		while (size > 0) {
			*(dest_buf_cpy--) = *(src_buf_cpy--);
			size--;
		}
	} else { // 没有重叠区域,从前往后拷贝
		while (size > 0) {
			*(dest_buf_cpy++) = *(src_buf_cpy++);
			size--;
		}
	}
	return dest_buf;
}





TestMain.cpp

#include "CommonFunction.h"

void Test(void)
{
    printf("----TestWeStrcpy------------------------------------\n");
    char dest1[1024];
    char src1[] = "abcd1234567890";
    char* dest_cpy1 = WeStrcpy(dest1, src1);
    printf("%s\n", dest_cpy1);
    printf("%s\n", dest1);

    printf("----TestWeStrncpy-----------------------------------\n");
    char dest2[1024];
    char src2[] = "abcd1234567890";
    char* dest_cpy2 = WeStrncpy(dest2, src2, 7);
    printf("%s\n", dest_cpy2);
    printf("%s\n", dest2);

    printf("----TestWeStrcat------------------------------------\n");
    char dest3[1024] = "10086";
    char src3[] = "abcd1234567890";
    char* dest_cpy3 = WeStrcat(dest3, src3);
    printf("%s\n", dest_cpy3);
    printf("%s\n", dest3);


    printf("----TestWeStrncat-----------------------------------\n");
    char dest4[1024] = "10086";
    char src4[] = "abcd1234567890";
    char* dest_cpy4 = WeStrncat(dest4, src4, 4);
    printf("%s\n", dest_cpy4);
    printf("%s\n", dest4);

    printf("----TestWeMemcpy-----------------------------------\n");
    char dest5[256];
    char src5[] = "abcd1234567890";
    char* dest_cpy5 = (char*)WeMemcpy(static_cast<void*>(dest5), static_cast<void*>(src5), sizeof(dest5));
    printf("%s\n", dest_cpy5);

    printf("----TestWeMemset-----------------------------------\n");
    char dest6[20];
    int value = 0;
    char* dest_cpy6 = (char*)WeMemset(static_cast<void*>(dest6), value, sizeof(dest6));
    for (int i = 0; i < sizeof(dest6); i++) {
        printf("%d ", dest_cpy6[i]);
    }
    printf("\n");

    printf("----TestWeMemmove---------------------------------\n");
    char dest7[256];
    char src7[] = "abcd1234567890";
    char* dest_cpy7 = (char*)WeMemcpy(static_cast<void*>(dest7), static_cast<void*>(src7), sizeof(dest7));
    printf("%s\n", dest_cpy7);
}


int main(int argc, char** argv)
{
    Test();
    return 0;
}

Linux下编译需要的Makefile

BIN_NAME = CommFuncTest


SRCS = $(wildcard ./*.cpp)
OBJS = $(patsubst %.cpp,%.o,$(SRCS))

CXX = g++

all:$(BIN_NAME)
$(BIN_NAME):$(OBJS)
	@echo Linking $(notdir $@)
	@$(CXX) -o $@ $^ -fpermissive

%.o:%.cpp
	@echo Compiling $<
	@$(CXX) -c $< -o $@

.PHONY:clean
clean:
	rm -rf *.o
	rm -rf $(BIN_NAME)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1. atof(): 将字符串转换为double类型的值。 例如: ```c++ char str[] = "3.14"; double num = atof(str); printf("%f", num); ``` 结果为:3.140000 2. atoi(): 将字符串转换为int类型的值。 例如: ```c++ char str[] = "1234"; int num = atoi(str); printf("%d", num); ``` 结果为:1234 3. atol(): 将字符串转换为long类型的值。 例如: ```c++ char str[] = "1234567"; long num = atol(str); printf("%ld", num); ``` 结果为:1234567 4. strtod(): 类似于atof(),将字符串转换为double类型的值。 例如: ```c++ char str[] = "3.14"; double num = strtod(str, NULL); printf("%f", num); ``` 结果为:3.140000 5. strtol(): 将字符串转换为long类型的值,同时支持指定转换的基数(例如10进制、16进制等)和错误检查。 例如: ```c++ char str[] = "0110"; long num = strtol(str, NULL, 2); printf("%ld", num); ``` 结果为:6 6. strtoul(): 类似于strtol(),不过返回的是无符号的long类型。 例如: ```c++ char str[] = "0xA"; unsigned long num = strtoul(str, NULL, 16); printf("%lu", num); ``` 结果为:10 7. memset(): 将一段内存区域设置为指定的值。 例如: ```c++ char str[10]; memset(str, 'a', sizeof(str)); printf("%s", str); ``` 结果为:aaaaaaa 8. memcpy(): 将一段内存区域的内容复制到另一段内存区域。 例如: ```c++ char src[] = "hello"; char dst[10]; memcpy(dst, src, sizeof(src)); printf("%s", dst); ``` 结果为:hello 9. memmove(): 和memcpy()类似,但是保证在有重叠的情况下会正确工作。 例如: ```c++ char str[] = "hello"; memmove(str + 2, str, 3); printf("%s", str); ``` 结果为:hehlo 10. memcmp(): 比较两段内存区域的内容是否相等。 例如: ```c++ char str1[] = "hello"; char str2[] = "Hello"; int result = memcmp(str1, str2, 5); printf("%d", result); ``` 结果为:32(h和H的ASCII码差值) 11. memchr(): 在一段内存区域中搜索指定的字符,并返回指向该字符的指针。 例如: ```c++ char str[] = "hello"; char* ptr = (char*)memchr(str, 'l', 5); printf("%s", ptr); ``` 结果为:ll 12. strcpy(): 将一个字符串复制到另一个字符串。 例如: ```c++ char src[] = "hello"; char dst[10]; strcpy(dst, src); printf("%s", dst); ``` 结果为:hello 13. strncpy(): 类似于strcpy(),不过只会复制指定长度的字符。 例如: ```c++ char src[] = "hello"; char dst[10]; strncpy(dst, src, 3); dst[3] = '\0'; printf("%s", dst); ``` 结果为:hel 14. strcat(): 将一个字符串附加到另一个字符串的末尾。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; strcat(str1, str2); printf("%s", str1); ``` 结果为:helloworld 15. strncat(): 类似于strcat(),不过只会附加指定长度的字符。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; strncat(str1, str2, 3); printf("%s", str1); ``` 结果为:helloworld 16. strcmp(): 比较两个字符串是否相等。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; int result = strcmp(str1, str2); printf("%d", result); ``` 结果为:-15 17. strncmp(): 类似于strcmp(),不过只会比较指定长度的字符。 例如: ```c++ char str1[] = "hello"; char str2[] = "world"; int result = strncmp(str1, str2, 3); printf("%d", result); ``` 结果为:0 18. strchr(): 在一个字符串中搜索指定的字符,并返回指向该字符的指针。 例如: ```c++ char str[] = "hello"; char* ptr = strchr(str, 'l'); printf("%s", ptr); ``` 结果为:llo 19. strrchr(): 类似于strchr(),不过会从字符串的末尾开始搜索。 例如: ```c++ char str[] = "hello"; char* ptr = strrchr(str, 'l'); printf("%s", ptr); ``` 结果为:lo 20. strstr(): 在一个字符串中搜索指定的子字符串,并返回指向该子字符串的指针。 例如: ```c++ char str[] = "hello world"; char* ptr = strstr(str, "world"); printf("%s", ptr); ``` 结果为:world
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神奇的小强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值