memccpy
Определено в заголовке <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");
// 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.");
}Вывод:
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) | конкатенирует две строки (функция) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/string/byte/memccpy