memccpy
From cppreference.com
Defined in header <string.h>
|
||
void *memccpy(void * restrict dest, const void * restrict src, int c, size_t count); |
(since C23) | |
Copies characters from the object pointed to by src
to the object pointed to by dest
, stopping after any of the next two conditions are satisfied:
-
count
characters are copied - the character (unsigned char)c is found (and copied).
-
The src
and dest
objects are interpreted as arrays of unsigned char.
The behavior is undefined if any condition is met:
- access occurs beyond the end of the
dest
array; - the objects overlap (which is a violation of the restrict contract)
- either
dest
orsrc
is an invalid or null pointer
- access occurs beyond the end of the
Parameters
dest | - | pointer to the object to copy to |
src | - | pointer to the object to copy from |
c | - | terminating character, converted to unsigned char at first |
count | - | number of characters to copy |
Return value
If the character (unsigned char)c was found memccpy
returns a pointer to the next character in dest
after (unsigned char)c, otherwise returns null pointer.
Notes
The function is identical to the POSIX memccpy.
memccpy(dest, src, 0, count) behaves similar to strncpy(dest, src, count), except that the former returns a pointer to the end of the buffer written, and does not zero-pad the destination array. Thus, memccpy
is useful for efficiently concatenating multiple strings.
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
Example
Run this code
#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"); // if `terminal` character was not found - print the whole `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."); } }
Output:
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
See also
(C11) |
copies one buffer to another (function) |
(C95)(C11) |
copies a certain amount of wide characters between two non-overlapping arrays (function) |
(C11) |
moves one buffer to another (function) |
(C11) |
copies one string to another (function) |
(C11) |
concatenates two strings (function) |