在得知strncmp
并非表面看起来的样子,以及系统(Linux)上没有strlcpy
函数之后,我决定尝试着自己写一个替代品。
我找到了libc维护者Ulrich Drepper发布的一段引用,其中提供了使用mempcpy
的strlcpy
替代方案。虽然我也没有mempcpy
,但它的行为很容易复制。首先,这是我使用的测试用例:
#include <stdio.h>
#include <string.h>
#define BSIZE 10
void insp(const char* s, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%c ", s[i]);
printf("\n");
for (i = 0; i < n; i++)
printf("%02X ", s[i]);
printf("\n");
return;
}
int copy_string(char *dest, const char *src, int n)
{
int r = strlen(memcpy(dest, src, n-1));
dest[r] = 0;
return r;
}
int main()
{
char b[BSIZE];
memset(b, 0, BSIZE);
printf("Buffer size is %d", BSIZE);
insp(b, BSIZE);
printf("\nFirst copy:\n");
copy_string(b, "First", BSIZE);
insp(b, BSIZE);
printf("b = '%s'\n", b);
printf("\nSecond copy:\n");
copy_string(b, "Second", BSIZE);
insp(b, BSIZE);
printf("b = '%s'\n", b);
return 0;
}
以下是它的结果:
Buffer size is 10
00 00 00 00 00 00 00 00 00 00
First copy:
F i r s t b =
46 69 72 73 74 00 62 20 3D 00
b = 'First'
Second copy:
S e c o n d
53 65 63 6F 6E 64 00 00 01 00
b = 'Second'
您可以在内部表示中看到(由
insp()
创建的行),存在一些混杂的噪音,比如第一次复制后检查中的printf()
格式字符串和第二次复制中的外来0x01。
这些字符串被完整地复制,并且它能正确处理过长的源字符串(现在先忽略将0作为长度传递给copy_string
可能出现的问题,稍后我会解决这个问题)。
但是为什么我的目标中有外来数组内容(来自格式字符串)呢?就好像目标实际上被调整大小以匹配新长度一样。
strlcpy()
和strlcat()
的源代码在自由许可下非常容易获取:http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/lib/libc/string/strlcpy.c?content-type=text%2Fplain - Michael Burr