memccpy
来自cppreference.com
<tbody>
</tbody>
| 在标头 <string.h> 定义
|
||
void* memccpy( void* restrict dest, const void* restrict src, int c, size_t count ); |
(C23 起) | |
从 src 所指向的对象复制字节到 dest 所指向的对象,在满足以下两个条件任何一个 后停止:
- 复制了
count个字节 - 找到(并复制)了字节
(unsigned char)c。
- 复制了
转译 src 与 dest 对象为 unsigned char 的数组。
若符合以下条件任何一个 则行为未定义:
- 出现越过数组
dest结尾的访问 - 对象重叠(这违反 restrict 契约)
dest或src为非法或空指针值
- 出现越过数组
参数
| dest | - | 指向要复制的对象的指针 |
| src | - | 指向复制来源对象的指针 |
| c | - | 终止字节,首先转换成 unsigned char
|
| count | - | 要复制的字节数 |
返回值
若找到字节 (unsigned char)c 则 memccpy 返回 dest 中 (unsigned char)c 后一字节的指针,否则返回空指针。
注解
函数等同于 POSIX memccpy。
memccpy(dest, src, 0, count) 行为类似于 strncpy(dest, src, count),但前者返回指向被写入缓冲区的末尾 的指针,并且不会以零填充目标数组。因而 memccpy 对高效连接多个字符串有用。
char bigString[1000];
char* end = bigString + sizeof bigString;
char* p = memccpy(bigString, "John, ", '\0', sizeof bigString - 1);
if (p)
p = memccpy(p - 1, "Paul, ", '\0', end - p);
if (p)
p = memccpy(p - 1, "George, ", '\0', end - p);
if (p)
p = memccpy(p - 1, "Joel ", '\0', end - p);
if (!p)
end[-1] = '\0';
puts(bigString); // John, Paul, George, Joel
示例
运行此代码
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
const char src[] = "Stars: Altair, Sun, Vega.";
const char terminal[] = {':', ' ', ',', '.', '!'};
char dest[sizeof src];
const char alt = '@';
for (size_t i = 0; i != sizeof terminal; ++i) {
void *to = memccpy(dest, src, terminal[i], sizeof dest);
printf("Terminal '%c' (%s):\t\"", terminal[i], to ? "found" : "absent");
// 若找不到 `terminal` 字符 - 打印整个 `dest`
to = to ? to : dest + sizeof dest;
for (char *from = dest; from != to; ++from)
putchar(isprint(*from) ? *from : alt);
puts("\"");
}
puts("\n" "Separate star names from distances (ly):");
const char *star_distance[] = {
"Arcturus : 37", "Vega : 25", "Capella : 43", "Rigel : 860", "Procyon : 11"
};
char names_only[64];
char *first = names_only;
char *last = names_only + sizeof names_only;
for (size_t t = 0; t != (sizeof star_distance) / (sizeof star_distance[0]); ++t)
{
if (first)
first = memccpy(first, star_distance[t], ' ', last - first);
else
break;
}
if (first)
{
*first = '\0';
puts(names_only);
}
else
puts("Buffer is too small.");
}
输出:
Terminal ':' (found): "Stars:"
Terminal ' ' (found): "Stars: "
Terminal ',' (found): "Stars: Altair,"
Terminal '.' (found): "Stars: Altair, Sun, Vega."
Terminal '!' (absent): "Stars: Altair, Sun, Vega.@"
Separate star names from distances (ly):
Arcturus Vega Capella Rigel Procyon
参阅
(C11) |
复制缓冲区到另一个 (函数) |
(C95)(C11) |
在两个不重叠的数组间复制一定数量的宽字符 (函数) |
(C11) |
移动缓冲区到另一个 (函数) |
(C11) |
复制字符串给另一个 (函数) |
(C11) |
连接两个字符串 (函数) |