memccpy
| Definiert in Header <string.h> |
||
| void* memccpy( void* restrict dest, const void* restrict src, int c, size_t count ); |
(seit C23) | |
Kopiert Bytes aus dem von src adressierten Objekt in das von dest adressierte Objekt und stoppt, nachdem eine der beiden folgenden Bedingungen erfüllt ist
- count Bytes kopiert wurden
- das Byte (unsigned char)c gefunden (und kopiert) wurde.
Die Objekte src und dest werden als Arrays von unsigned char interpretiert.
Das Verhalten ist undefiniert, wenn eine der Bedingungen erfüllt ist
- ein Zugriff über das Ende des Arrays dest hinaus erfolgt;
- die Objekte sich überlappen (was eine Verletzung des restrict-Vertrags darstellt)
- dest oder src ein ungültiger oder Null-Zeiger ist
Inhalt |
[edit] Parameter
| dest | - | Zeiger auf das zu kopierende Objekt |
| src | - | Zeiger auf das zu kopierende Objekt |
| c | - | Terminierungsbyte, zuerst in unsigned char konvertiert |
| zählt | - | Anzahl der zu kopierenden Bytes |
[edit] Rückgabewert
Wenn das Byte (unsigned char)c gefunden wurde, gibt `memccpy` einen Zeiger auf das nächste Byte in dest nach (unsigned char)c zurück. Andernfalls gibt es einen Null-Zeiger zurück.
[edit] Anmerkungen
Die Funktion ist identisch mit der POSIX memccpy.
memccpy(dest, src, 0, count) verhält sich ähnlich wie strncpy(dest, src, count), außer dass die erstere einen Zeiger auf das *Ende* des geschriebenen Puffers zurückgibt und das Zielarray nicht mit Nullen auffüllt. Daher ist `memccpy` nützlich für das effiziente Verketten mehrerer Zeichenketten.
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] Beispiel
#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."); }
Ausgabe
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] Siehe auch
| (C11) |
kopiert einen Puffer in einen anderen (Funktion) |
| (C95)(C11) |
kopiert eine bestimmte Anzahl breiter Zeichen zwischen zwei nicht überlappenden Arrays (Funktion) |
| (C11) |
verschiebt einen Puffer in einen anderen (Funktion) |
| (C11) |
kopiert einen String in einen anderen (Funktion) |
| (C11) |
verbindet zwei Strings (Funktion) |