我必须从标准 C 库中实现我自己版本的 strlcat() 函数。
size_t strlcat(char * restrict dst, const char * restrict src, size_t size);
Run Code Online (Sandbox Code Playgroud)
我有两个关于它如何工作的问题:
dst在每种情况下都以NUL_terminates 结尾?在我的男人中,我有以下几点:
strlcat() 获取缓冲区的完整大小(不仅仅是长度)并保证以 NUL 终止结果(只要大小大于 0,或者在 strlcat() 的情况下,只要至少是dst 中有 1 个字节可用)。
和 :
strlcat() 函数将 NUL 终止的字符串 src 附加到 dst 的末尾。它将最多附加 size - strlen(dst) - 1 个字节,NUL 终止结果。
但是也 :
但是请注意,如果 strlcat() 在没有找到 NUL 的情况下遍历 size 个字符,则字符串的长度被认为是 size 并且目标字符串不会以 NUL 结尾(因为 NUL 没有空间)。
那么,我应该在每种情况下 NUL_terminate dst 吗?一方面,它表示存在dst字符串不是 NUL_terminated 的情况。另一方面,该男子说strlcat()保证dst将是 NUL_terminated,并且非 NUL_terminated 字符串不会非常不安全吗?
有人可以给我一个例子,这种情况会发生吗?
以下是我通过一些测试得到的结果:
Before : || After :
dst | src | size || dst | return
------------------------||--------------------
dst\0 | src\0 | 0 || dst\0 | 3
dst\0 | src\0 | 1 || dst\0 | 4
dst\0 | src\0 | 2 || dst\0 | 5
dst\0 | src\0 | 3 || dst\0 | 6
dst\0 | src\0 | 4 || dst\0 | 6
dst\0 | src\0 | 5 || dsts\0 | 6
dst\0 | src\0 | 6 || dstsr\0 | 6
dst\0 | src\0 | 7 || dstsrc\0 | 6
dst\0 | src\0 | 8 || dstsrc\0 | 6
Run Code Online (Sandbox Code Playgroud)
再次来自男人:
[strlcat() 函数] 返回 [它试图] 创建的字符串的总长度。对于 strlcat() 这意味着 dst 的初始长度加上 src 的长度。
dst's 和src's 的大小在我的测试中是恒定的(3 和 3)。那么为什么会出现返回值与 6 不同的情况呢?
不是(len(dst) + min(size, len(src))吗?
大小代表什么?
strlcat() 函数将 NUL 终止的字符串 src 附加到 dst 的末尾。它将最多附加 size - strlen(dst) - 1 个字节,NUL 终止结果。
所以大小应该是最后dst允许的长度(包括'\0'字符)?那正确吗?
dst吗?dst将被strlcatifstrlcat修改为空终止dst。dst如果dst已经被完全占用,strlcat 不会修改。dst如果NUL在的第一个size - 1字节中没有找到dst(或者如果size是 0),则认为已被完全占用。
所以有两种情况dst不会被空终止strlcat。一种是dst完全以空字符结尾的size - 1字节字符串,在这种情况下,它不会被修改并继续以空字符结尾。第二种情况是dst最初没有以空值终止,在这种情况下,在调用strlcat.
size预期为包含 的内存区域的大小dst,因此dst[size]假定为无效内存引用。因此,如果dst开始了作为一个有效的(并且因此空终止)串,其长度会比严格少size并且strlcat将使用strlen(dst)作为其长度。如果dst无效,则假定其大小size用于返回值。在这种情况下,dst将不会被修改。看上面。