1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
<h1 id="firstHeading" class="firstHeading">memccpy</h1> <table class="t-dcl-begin"> <tr class="t-dsc-header"> <th> Defined in header <code><string.h></code> </th> <th> </th> <th> </th> </tr> <tr class="t-dcl t-since-c23"> <td> <pre data-language="c">void* memccpy( void* restrict dest, const void* restrict src, int c, size_t count );</pre>
</td> <td class="t-dcl-nopad"> </td> <td> <span class="t-mark-rev t-since-c23">(since C23)</span> </td> </tr> </table> <p>Copies bytes from the object pointed to by <code>src</code> to the object pointed to by <code>dest</code>, stopping after <i>any</i> of the next two conditions are satisfied:</p>
<ul>
<li> <code>count</code> bytes are copied </li>
<li> the byte <code>(unsigned char)c</code> is found (and copied). </li>
</ul> <p>The <code>src</code> and <code>dest</code> objects are interpreted as arrays of <code>unsigned char</code>.</p>
<p>The behavior is undefined if <i>any</i> condition is met:</p>
<ul>
<li> access occurs beyond the end of the <code>dest</code> array; </li>
<li> the objects overlap (which is a violation of the <a href="../../language/restrict" title="c/language/restrict"><code>restrict</code></a> contract) </li>
<li> either <code>dest</code> or <code>src</code> is an invalid or null pointer </li>
</ul> <h3 id="Parameters"> Parameters</h3> <table class="t-par-begin"> <tr class="t-par"> <td> dest </td> <td> - </td> <td> pointer to the object to copy to </td>
</tr> <tr class="t-par"> <td> src </td> <td> - </td> <td> pointer to the object to copy from </td>
</tr> <tr class="t-par"> <td> c </td> <td> - </td> <td> terminating byte, converted to <code>unsigned char</code> at first </td>
</tr> <tr class="t-par"> <td> count </td> <td> - </td> <td> number of bytes to copy </td>
</tr>
</table> <h3 id="Return_value"> Return value</h3> <p>If the byte <code>(unsigned char)c</code> was found, <code>memccpy</code> returns a pointer to the next byte in <code>dest</code> after <code>(unsigned char)c</code>. Otherwise it returns a null pointer.</p>
<h3 id="Notes"> Notes</h3> <p>The function is identical to the <a rel="nofollow" class="external text" href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/memccpy.html">POSIX <code>memccpy</code></a>.</p>
<p><code>memccpy(dest, src, 0, count)</code> behaves similar to <code><a href="http://en.cppreference.com/w/c/string/byte/strncpy"><span class="kw554">strncpy</span></a><span class="br0">(</span>dest, src, count<span class="br0">)</span></code>, except that the former returns a pointer to the <i>end</i> of the buffer written, and does not zero-pad the destination array. Thus, <code>memccpy</code> is useful for efficiently concatenating multiple strings.</p>
<div class="c source-c"><pre data-language="c">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</pre></div> <h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">#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.");
}</pre></div> <p>Output:</p>
<div class="text source-text"><pre data-language="c">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</pre></div> </div> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td> <div><a href="memcpy" title="c/string/byte/memcpy"> <span class="t-lines"><span>memcpy</span><span>memcpy_s</span></span></a></div>
<div><span class="t-lines"><span><span class="t-mark-rev t-since-c11">(C11)</span></span></span></div> </td> <td> copies one buffer to another <br> <span class="t-mark">(function)</span> </td>
</tr> <tr class="t-dsc"> <td> <div><a href="../wide/wmemcpy" title="c/string/wide/wmemcpy"> <span class="t-lines"><span>wmemcpy</span><span>wmemcpy_s</span></span></a></div>
<div><span class="t-lines"><span><span class="t-mark-rev t-since-c95">(C95)</span></span><span><span class="t-mark-rev t-since-c11">(C11)</span></span></span></div> </td> <td> copies a certain amount of wide characters between two non-overlapping arrays <br> <span class="t-mark">(function)</span> </td>
</tr> <tr class="t-dsc"> <td> <div><a href="memmove" title="c/string/byte/memmove"> <span class="t-lines"><span>memmove</span><span>memmove_s</span></span></a></div>
<div><span class="t-lines"><span><span class="t-mark-rev t-since-c11">(C11)</span></span></span></div> </td> <td> moves one buffer to another <br> <span class="t-mark">(function)</span> </td>
</tr> <tr class="t-dsc"> <td> <div><a href="strcpy" title="c/string/byte/strcpy"> <span class="t-lines"><span>strcpy</span><span>strcpy_s</span></span></a></div>
<div><span class="t-lines"><span><span class="t-mark-rev t-since-c11">(C11)</span></span></span></div> </td> <td> copies one string to another <br> <span class="t-mark">(function)</span> </td>
</tr> <tr class="t-dsc"> <td> <div><a href="strcat" title="c/string/byte/strcat"> <span class="t-lines"><span>strcat</span><span>strcat_s</span></span></a></div>
<div><span class="t-lines"><span><span class="t-mark-rev t-since-c11">(C11)</span></span></span></div> </td> <td> concatenates two strings <br> <span class="t-mark">(function)</span> </td>
</tr> </table> <div class="_attribution">
<p class="_attribution-p">
© cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
<a href="https://en.cppreference.com/w/c/string/byte/memccpy" class="_attribution-link">https://en.cppreference.com/w/c/string/byte/memccpy</a>
</p>
</div>
|