memcpy、strcpy、strncpy、strlen、strcat几个函数的实现

本文提供了字符串操作函数如memcpy、strcpy、strncpy、strlen、strcat和strcmp的手写实现代码,详细解释了每种函数的不同实现方式及其注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、memcpy实现:

void* mymemcpy(void* dest, const void* src, size_t count) {
	assert(dest != NULL && src != NULL);
	char* pdest = static_cast<char*>(dest);
	const char* psrc = static_cast<const char*>(src);
	if(pdest > psrc && pdest < psrc+count) {
		for(size_t i = count-1; i != -1; i--) {
			pdest[i] = psrc[i];
		}
	}
	else {
		for(size_t i = 0; i < count; i++) {
			pdest[i] = psrc[i];
		}
	}
	return dest;
}


二、strcpy实现:

//比较典型的实现方法
char* mystrcpy(char* dest, const char* src) {
	if(dest == NULL || src == NULL) return NULL;
	if(dest == src) {
		return dest;
	}
	char* tempptr = dest;
	while((*dest++ = *src++) != '\0');
	return tempptr;
}

//更为严谨的实现方法(考虑内存叠加的情况,但是这样可能会有内存越界的情况,显然是不安全的。虽然实际调用strcpy的时候也可以支持strcpy(str+1, str)这种情况,但是这样做显然是不安全的。这个实现方法只是为了更接近真实的strcpy)
char* mystrcpy1(char* dest, const char* src) {
	assert(dest != NULL && src != NULL);
	char* psrc = const_cast<char*>(src);
    size_t len_src = 0;
	while(*psrc++ != '\0') len_src++;
	if(dest > src && dest < src+len_src) {
		for(size_t i = len_src; i != -1; i--) {
			dest[i] = src[i];
		}
	}
	else {
		for(size_t i = 0; i <= len_src; i++) {
			dest[i] = src[i];
		}
	}
	return dest;
}

三、strncpy实现:

char* mystrncpy(char* dest, const char* src, size_t count) {
	assert(dest != NULL && src != NULL);
	size_t i = 0;
	for(i = 0; i < count; i++) {
		dest[i] = src[i];
		if(dest[i] == '\0') break;
	}
	if(i == count) dest[i] = '\0';
	return dest;
}


四、strlen实现:

//使用一个中间变量实现
size_t mystrlen(const char* str) {
	if(str == NULL || *str == '\0') {
		return 0;
	}
	size_t count = 0;
	while(*str++ != '\0') {
		count++;
	}
	return count;
}

//不使用中间变量,递归实现方法1
size_t mystrlen1(const char* str) {
	if(str == NULL || *str == '\0') {
		return 0;
	}
	return mystrlen(str+1) + 1;
}

//不使用中间变量,递归实现方法2
size_t mystrlen2(const char* str) {
	if(str == NULL ) {
		return 0;
	}
	return *str ? (mystrlen2(++str)+1) : 0;
}


五、strcat实现:

char* mystrcat(char* dest, const char* src) {
	char* tempptr = dest;
	while(*dest != '\0') dest++;
	while((*dest++ = *src++) != '\0');
	return tempptr;
}

六、strcmp实现:

int mystrcmp(const char* str1, const char* str2) {
	int ret = 0;
	while(!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str1) {
		str1++;
		str2++;
	}
	if(ret > 0)
		return 1;
	else if(ret < 0)
		return -1;
	else
		return 0;
}



记录在此,方便以后回顾。


<think>好的,我需要回答用户关于C语言中strcat函数的功能和使用说明的问题。首先,我需要回忆一下strcat的基本作用。strcat是字符串连接函数,用于将源字符串追加到目标字符串的末尾。根据用户提供的引用资料,比如引用[1]提到它用于字符串拼接,将两个字符串连接在一起,参数包括目标字符串和源字符串,返回指向目标字符串的指针。 接下来,我要组织回答的结构,确保符合用户的要求:结构清晰,分步说明。首先介绍功能,然后是参数和返回值,接着是使用说明,最后是注意事项和示例代码。需要特别注意LaTeX格式的要求,行内公式用$...$,独立公式用$$...$$,但在这个问题中可能用不到数学公式,但如果有涉及到变量名或代码中的符号,可能需要用行内格式。 然后,根据引用资料中的信息,比如引用[2]提到函数定义是char *strcat(char *dest, const char *src);,所以需要详细解释参数dest和src的作用,dest必须有足够的空间,否则会导致溢出。引用[4]提到在追加时会覆盖目标字符串的结束符'\0',并在最后添加新的结束符,这一点需要注意,说明目标字符串的末尾必须有足够的空间。 此外,用户可能关心使用示例,需要给出代码示例,并确保代码语法正确。比如,引用[3]提供了自定义的strcat实现,但用户可能需要标准库的使用示例。因此,给出一个简单的例子,展示如何正确使用strcat函数,包括正确的头文件引入和缓冲区分配。 还需要注意安全性问题,比如strcat不会检查目标缓冲区的大小,可能导致缓冲区溢出,引用[1]中提到strcpy_s和memcpy_s等安全函数,可以建议使用更安全的替代函数如strncat或strcat_s(如果可用)。 最后,生成相关问题,参考用户示例中的问题类型,可能涉及函数实现、安全使用、与其他函数的区别等。</think>### C语言 `strcat` 函数功能及使用说明 #### 1. 功能 `strcat`(string concatenation)是C语言标准库中的字符串拼接函数,用于将**源字符串**(`src`)追加到**目标字符串**(`dest`)的末尾,覆盖目标字符串原有的终止符`\0`,并在拼接后的字符串末尾添加新的`\0`[^1][^4]。 #### 2. 函数原型 ```c char* strcat(char* dest, const char* src); ``` - **参数**: - `dest`:目标字符串,需为可修改的字符数组,且必须有足够的空间容纳拼接后的结果[^1][^2]。 - `src`:源字符串,以`\0`结尾的常量字符串。 - **返回值**:返回指向目标字符串`dest`的指针。 #### 3. 使用说明 ##### 步骤1:确保目标字符串空间充足 目标字符串`dest`的长度应至少为`strlen(dest) + strlen(src) + 1`(额外`+1`用于存放终止符`\0`)。若空间不足,会导致**缓冲区溢出**,引发未定义行为[^1]。 ##### 步骤2:调用函数 ```c #include <string.h> // 引入头文件 char dest[20] = "Hello"; const char* src = " World!"; strcat(dest, src); // 拼接后 dest 变为 "Hello World!" ``` ##### 步骤3:验证结果 拼接后`dest`的内容为`"Hello World!\0"`,且返回值与`dest`地址相同。 #### 4. 注意事项 1. **缓冲区溢出风险**:`strcat`不会检查目标字符串的剩余空间,需手动确保安全[^1]。 - 替代方案:使用更安全的`strncat`或`strcat_s`(C11标准)。 ```c strncat(dest, src, sizeof(dest) - strlen(dest) - 1); // 限制追加长度 ``` 2. **不可用于常量字符串**:目标字符串必须是可修改的字符数组。 ```c char* dest = "Hello"; // 错误!常量字符串不可修改 ``` #### 5. 示例代码 ```c #include <stdio.h> #include <string.h> int main() { char dest[20] = "Hello"; const char* src = " World!"; strcat(dest, src); printf("拼接结果: %s\n", dest); // 输出 "Hello World!" return 0; } ``` #### 6. 与其他字符串函数对比 | 函数 | 功能 | 安全性 | |-----------|--------------------|----------------------| | `strcpy` | 字符串拷贝 | 无检查 | | `strcat` | 字符串拼接 | 无检查 | | `strncpy` | 限定长度的拷贝 | 部分检查 | | `strncat` | 限定长度的拼接 | 部分检查 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值