刷题笔记16——字符串循环、strcpy实现(考虑内存重叠)

思路

刷题笔记16——字符串循环、strcpy实现(考虑内存重叠)

char s[] = “hello”;
strcpy(s+1, s); //应返回hell,但实际会报错,因为dst与src重叠了,把’\0’覆盖了
所谓重叠, 就是src未处理的部分已经被dst给覆盖了, 只有一种情况:src <= dst <= src + strlen(src)
C函数memcpy自带内存重叠检测功能, 下面给出memcpy的实现my_memcpy.

刷题笔记16——字符串循环、strcpy实现(考虑内存重叠)

代码及运行效果

刷题笔记16——字符串循环、strcpy实现(考虑内存重叠)

#include <iostream>
#include <assert.h>
using namespace std;

char *my_strcpy(char *dst, const char *src) {
	assert(dst != NULL && src != NULL);
	char *ret = dst;
	int size = sizeof(src);
	if (dst >= src && dst <= src + size - 1) {
		// 内存重叠,从高地址开始拷贝
		dst = dst + size - 1;
		src = src + size - 1;
		while (size--)
			*dst-- = *src--;
	}
	else {
		while (*src != '\0')
			*dst++ = *src++;
		*dst = '\0';
	}
	return ret;
}

void loopMove(char *src, int step) {
	int len = strlen(src);
	if (step < 0 || step > len) {
		cout << "移动位数不合理!\n";
		return;
	}
	else if (len == 0) {
		cout << "空串!\n";
		return;
	}
	else {
		char *new_begin = src + len - step;
		char *src_last = src + len;
		char *tmp = src;
		int k = len - step;
		while (k-- > 0) {
			*src_last++ = *tmp++;
		}
		*src_last = '\0';
		my_strcpy(src, new_begin);
	}
}

int main() {

	char a[] = "abcdefghi";
	cout << "原字符串: " << a << endl;

	int b;
	cout << "请输入要移动的位数: ";
	while (cin >> b) {
		loopMove(a, b);
		cout << a << endl;
		cout << "请输入要移动的位数: ";
	}


	return 0;
}