memccpy
From cppreference.com
| ヘッダー <string.h> で定義 |
||
| void* memccpy( void* restrict dest, const void* restrict src, int c, size_t count ); |
(C23以降) | |
srcで指されるオブジェクトからdestで指されるオブジェクトにバイトをコピーします。ただし、次の2つの条件のいずれかが満たされた後に停止します。
-
countバイトがコピーされた - バイト `(unsigned char)c` が見つかった(そしてコピーされた)。
-
srcおよびdestオブジェクトは、unsigned charの配列として解釈されます。
以下のいずれかの条件が満たされた場合、動作は未定義です。
dest配列の末尾を超えてアクセスが発生した場合。- オブジェクトがオーバーラップしている場合(これは
restrict契約違反です)。 destまたはsrcが無効なポインタまたはヌルポインタである場合。
目次 |
[編集] パラメータ
| dest | - | コピー先のオブジェクトへのポインタ |
| src | - | コピー元のオブジェクトへのポインタ |
| c | - | 終端バイト。最初にunsigned charに変換されます。 |
| count | - | 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) |
オーバーラップしていない2つの配列間で、指定された数のワイド文字をコピーする (関数) |
| (C11) |
あるバッファを別のバッファに移動する (関数) |
| (C11) |
ある文字列を別の文字列にコピーする (関数) |
| (C11) |
2つの文字列を連結する (関数) |