memccpy
From cppreference.com
C
Concurrency support (C11)
Null-terminated byte strings
Functions
Character manipulation
Conversions to and from numeric formats
(C99)(C99)
(C99)(C99)
(C23)(C23)(C23)
String manipulation
String examination
Memory manipulation
Miscellaneous
(C11)(C11)
Defined in header
<string.h>
void* memccpy( void* restrict dest, const void* restrict src, int c, size_t count );
(since C23)
Copies bytes 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 bytes are copied
- the byte (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 or src is an invalid or null pointer
Contents
[edit] Parameters
dest
-
pointer to the object to copy to
src
-
pointer to the object to copy from
c
-
terminating byte, converted to unsigned char at first
count
-
number of bytes to copy
[edit] Return value
If the byte (unsigned char)c was found, memccpy
returns a pointer to the next byte in dest after (unsigned char)c. Otherwise it returns a null pointer.
[edit] 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 - 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
[edit] 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
[edit] See also
(C95)(C11)
(function) [edit]