Namespaces
Variants

memccpy

From cppreference.net
< c ‎ | string ‎ | byte
Определено в заголовке <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
**Примечание:** Весь код C++ оставлен без изменений, включая имена переменных, функции и комментарии, как было указано в требованиях. HTML-разметка также сохранена в оригинальном виде.

Пример

#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

Смотрите также

копирует один буфер в другой
(функция)
копирует определённое количество широких символов между двумя неперекрывающимися массивами
(функция)
перемещает один буфер в другой
(функция)
копирует одну строку в другую
(функция)
объединяет две строки
(функция)