Spec-Zone.ru › C

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

См. также

memcpymemcpy_s
(C11)
копирует один буфер в другой
(функция)
wmemcpywmemcpy_s
(C95)(C11)
копирует определенное количество широких символов между двумя неперекрывающимися массивами
(функция)
memmovememmove_s
(C11)
перемещает один буфер в другой
(функция)
strcpystrcpy_s
(C11)
копирует одну строку в другую
(функция)
strcatstrcat_s
(C11)
конкатенирует две строки
(функция)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/string/byte/memccpy

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API