模拟实现strncpy
strncpy就是将src中的n个字符拷贝到dest中,要注意几个点:
-
如果src长度小于len,用‘\0’ 补齐len的长度。注意用strlen判断src长度时,要明白strlen是向后找‘\0’来计算长度,所以,如果是用单个字符赋值,不要忘记在结尾加上‘\0’,如果要给src限定长度时也不要忘记算上‘\0’的长度
-
如果src长度大于len,只会拷贝len个字符,且不会以’\0’结束。
-
有时候还要考虑到内存重叠的问题,这里给出了两种方法,同样不要忘了判断src长度小于len的情况
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
//不考虑内存重叠
char* MyStrncpy1(char* dest, const char* src, size_t len)
{
assert(NULL != dest && NULL != src);
char* ret = dest;
int offset = 0;
if (strlen(src) < len) //判断源字符串长度是否小于len
{
offset = len - strlen(src);
len = strlen(src);
}
while (len--)
{
*dest++ = *src++;
}
while (offset--) //如果源字符串长度小于len,此时需要手动用'\0'补齐len
{
*dest++ = '\0';
}
return ret;
}
//考虑内存重叠
char* MyStrncpy2(char* dest, const char* src, size_t len)
{
assert(NULL != dest && NULL != src);
char* ret = dest;
char* tmp = NULL;
int offset = 0;
if (strlen(src) < len) //判断源字符串长度是否小于len
{
offset = len - strlen(src);
len = strlen(src);
}
if (dest > src && dest < src + len) //内存重叠,从后往前复制
{
dest = dest + len - 1;
src = src + len - 1;
tmp = dest; //用来记住dest的最后位置,以便源字符串长度小于len时,在后面用'\0'补全len
while (len--)
*dest-- = *src--;
}
else
{
while (len--)
{
*dest++ = *src++;
tmp = dest;
}
}
while (offset--) //如果源字符串长度小于len,此时需要手动用'\0'补齐len
{
*tmp++ = '\0';
}
return ret;
}
int main()
{
char arr1[4] = "Hi!"; //注意留'\0'的空间
char arr2[5] = {0};
printf("%s\n", MyStrncpy1(arr2, arr1, 5));
return 0;
}
这里主要来测试src<len的情况,用‘\0’补全