memccpy
来自cppreference.com
在标头 <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); 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); 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) |
连接两个字符串 (函数) |