Next: String/Array Comparison, Previous: String Length, Up: String and Array Utilities
You can use the functions described in this section to copy the contents of strings and arrays, or to append the contents of one string to another. The `str' and `mem' functions are declared in the header file string.h while the `wstr' and `wmem' functions are declared in the file wchar.h. A helpful way to remember the ordering of the arguments to the functions in this section is that it corresponds to an assignment expression, with the destination array specified to the left of the source array. All of these functions return the address of the destination array.
Most of these functions do not work properly if the source and destination arrays overlap. For example, if the beginning of the destination array overlaps the end of the source array, the original contents of that part of the source array may get overwritten before it is copied. Even worse, in the case of the string functions, the null character marking the end of the string may be lost, and the copy function might get stuck in a loop trashing all the memory allocated to your program.
All functions that have problems copying between overlapping arrays are
explicitly identified in this manual. In addition to functions in this
section, there are a few others like sprintf (see Formatted Output Functions) and scanf (see Formatted Input Functions).
The
memcpyfunction copies size bytes from the object beginning at from into the object beginning at to. The behavior of this function is undefined if the two arrays to and from overlap; usememmoveinstead if overlapping is possible.The value returned by
memcpyis the value of to.Here is an example of how you might use
memcpyto copy the contents of an array:struct foo *oldarray, *newarray; int arraysize; ... memcpy (new, old, arraysize * sizeof (struct foo));
The
wmemcpyfunction copies size wide characters from the object beginning at wfrom into the object beginning at wto. The behavior of this function is undefined if the two arrays wto and wfrom overlap; usewmemmoveinstead if overlapping is possible.The following is a possible implementation of
wmemcpybut there are more optimizations possible.wchar_t * wmemcpy (wchar_t *restrict wto, const wchar_t *restrict wfrom, size_t size) { return (wchar_t *) memcpy (wto, wfrom, size * sizeof (wchar_t)); }The value returned by
wmemcpyis the value of wto.This function was introduced in Amendment 1 to ISO C90.
The
mempcpyfunction is nearly identical to thememcpyfunction. It copies size bytes from the object beginning atfrominto the object pointed to by to. But instead of returning the value of to it returns a pointer to the byte following the last written byte in the object beginning at to. I.e., the value is((void *) ((char *)to+size)).This function is useful in situations where a number of objects shall be copied to consecutive memory positions.
void * combine (void *o1, size_t s1, void *o2, size_t s2) { void *result = malloc (s1 + s2); if (result != NULL) mempcpy (mempcpy (result, o1, s1), o2, s2); return result; }This function is a GNU extension.
The
wmempcpyfunction is nearly identical to thewmemcpyfunction. It copies size wide characters from the object beginning atwfrominto the object pointed to by wto. But instead of returning the value of wto it returns a pointer to the wide character following the last written wide character in the object beginning at wto. I.e., the value is wto+size.This function is useful in situations where a number of objects shall be copied to consecutive memory positions.
The following is a possible implementation of
wmemcpybut there are more optimizations possible.wchar_t * wmempcpy (wchar_t *restrict wto, const wchar_t *restrict wfrom, size_t size) { return (wchar_t *) mempcpy (wto, wfrom, size * sizeof (wchar_t)); }This function is a GNU extension.
memmovecopies the size bytes at from into the size bytes at to, even if those two blocks of space overlap. In the case of overlap,memmoveis careful to copy the original values of the bytes in the block at from, including those bytes which also belong to the block at to.The value returned by
memmoveis the value of to.
wmemmovecopies the size wide characters at wfrom into the size wide characters at wto, even if those two blocks of space overlap. In the case of overlap,memmoveis careful to copy the original values of the wide characters in the block at wfrom, including those wide characters which also belong to the block at wto.The following is a possible implementation of
wmemcpybut there are more optimizations possible.wchar_t * wmempcpy (wchar_t *restrict wto, const wchar_t *restrict wfrom, size_t size) { return (wchar_t *) mempcpy (wto, wfrom, size * sizeof (wchar_t)); }The value returned by
wmemmoveis the value of wto.This function is a GNU extension.
This function copies no more than size bytes from from to to, stopping if a byte matching c is found. The return value is a pointer into to one byte past where c was copied, or a null pointer if no byte matching c appeared in the first size bytes of from.
This function copies the value of c (converted to an
unsigned char) into each of the first size bytes of the object beginning at block. It returns the value of block.
This function copies the value of wc into each of the first size wide characters of the object beginning at block. It returns the value of block.
This copies characters from the string from (up to and including the terminating null character) into the string to. Like
memcpy, this function has undefined results if the strings overlap. The return value is the value of to.
This copies wide characters from the string wfrom (up to and including the terminating null wide character) into the string wto. Like
wmemcpy, this function has undefined results if the strings overlap. The return value is the value of wto.
This function is similar to
strcpybut always copies exactly size characters into to.If the length of from is more than size, then
strncpycopies just the first size characters. Note that in this case there is no null terminator written into to.If the length of from is less than size, then
strncpycopies all of from, followed by enough null characters to add up to size characters in all. This behavior is rarely useful, but it is specified by the ISO C standard.The behavior of
strncpyis undefined if the strings overlap.Using
strncpyas opposed tostrcpyis a way to avoid bugs relating to writing past the end of the allocated space for to. However, it can also make your program much slower in one common case: copying a string which is probably small into a potentially large buffer. In this case, size may be large, and when it is,strncpywill waste a considerable amount of time copying null characters.
This function is similar to
wcscpybut always copies exactly size wide characters into wto.If the length of wfrom is more than size, then
wcsncpycopies just the first size wide characters. Note that in this case there is no null terminator written into wto.If the length of wfrom is less than size, then
wcsncpycopies all of wfrom, followed by enough null wide characters to add up to size wide characters in all. This behavior is rarely useful, but it is specified by the ISO C standard.The behavior of
wcsncpyis undefined if the strings overlap.Using
wcsncpyas opposed towcscpyis a way to avoid bugs relating to writing past the end of the allocated space for wto. However, it can also make your program much slower in one common case: copying a string which is probably small into a potentially large buffer. In this case, size may be large, and when it is,wcsncpywill waste a considerable amount of time copying null wide characters.
This function copies the null-terminated string s into a newly allocated string. The string is allocated using
malloc; see Unconstrained Allocation. Ifmalloccannot allocate space for the new string,strdupreturns a null pointer. Otherwise it returns a pointer to the new string.
This function copies the null-terminated wide character string ws into a newly allocated string. The string is allocated using
malloc; see Unconstrained Allocation. Ifmalloccannot allocate space for the new string,wcsdupreturns a null pointer. Otherwise it returns a pointer to the new wide character string.This function is a GNU extension.
This function is similar to
strdupbut always copies at most size characters into the newly allocated string.If the length of s is more than size, then
strndupcopies just the first size characters and adds a closing null terminator. Otherwise all characters are copied and the string is terminated.This function is different to
strncpyin that it always terminates the destination string.
strndupis a GNU extension.
This function is like
strcpy, except that it returns a pointer to the end of the string to (that is, the address of the terminating null characterto + strlen (from)) rather than the beginning.For example, this program uses
stpcpyto concatenate `foo' and `bar' to produce `foobar', which it then prints.#include <string.h> #include <stdio.h> int main (void) { char buffer[10]; char *to = buffer; to = stpcpy (to, "foo"); to = stpcpy (to, "bar"); puts (buffer); return 0; }This function is not part of the ISO or POSIX standards, and is not customary on Unix systems, but we did not invent it either. Perhaps it comes from MS-DOG.
Its behavior is undefined if the strings overlap. The function is declared in string.h.
This function is like
wcscpy, except that it returns a pointer to the end of the string wto (that is, the address of the terminating null characterwto + strlen (wfrom)) rather than the beginning.This function is not part of ISO or POSIX but was found useful while developing the GNU C Library itself.
The behavior of
wcpcpyis undefined if the strings overlap.
wcpcpyis a GNU extension and is declared in wchar.h.
This function is similar to
stpcpybut copies always exactly size characters into to.If the length of from is more then size, then
stpncpycopies just the first size characters and returns a pointer to the character directly following the one which was copied last. Note that in this case there is no null terminator written into to.If the length of from is less than size, then
stpncpycopies all of from, followed by enough null characters to add up to size characters in all. This behavior is rarely useful, but it is implemented to be useful in contexts where this behavior of thestrncpyis used.stpncpyreturns a pointer to the first written null character.This function is not part of ISO or POSIX but was found useful while developing the GNU C Library itself.
Its behavior is undefined if the strings overlap. The function is declared in string.h.
This function is similar to
wcpcpybut copies always exactly wsize characters into wto.If the length of wfrom is more then size, then
wcpncpycopies just the first size wide characters and returns a pointer to the wide character directly following the last non-null wide character which was copied last. Note that in this case there is no null terminator written into wto.If the length of wfrom is less than size, then
wcpncpycopies all of wfrom, followed by enough null characters to add up to size characters in all. This behavior is rarely useful, but it is implemented to be useful in contexts where this behavior of thewcsncpyis used.wcpncpyreturns a pointer to the first written null character.This function is not part of ISO or POSIX but was found useful while developing the GNU C Library itself.
Its behavior is undefined if the strings overlap.
wcpncpyis a GNU extension and is declared in wchar.h.
This macro is similar to
strdupbut allocates the new string usingallocainstead ofmalloc(see Variable Size Automatic). This means of course the returned string has the same limitations as any block of memory allocated usingalloca.For obvious reasons
strdupais implemented only as a macro; you cannot get the address of this function. Despite this limitation it is a useful function. The following code shows a situation where usingmallocwould be a lot more expensive.#include <paths.h> #include <string.h> #include <stdio.h> const char path[] = _PATH_STDPATH; int main (void) { char *wr_path = strdupa (path); char *cp = strtok (wr_path, ":"); while (cp != NULL) { puts (cp); cp = strtok (NULL, ":"); } return 0; }Please note that calling
strtokusing path directly is invalid. It is also not allowed to callstrdupain the argument list ofstrtoksincestrdupausesalloca(see Variable Size Automatic) can interfere with the parameter passing.This function is only available if GNU CC is used.
This function is similar to
strndupbut likestrdupait allocates the new string usingallocasee Variable Size Automatic. The same advantages and limitations ofstrdupaare valid forstrndupa, too.This function is implemented only as a macro, just like
strdupa. Just asstrdupathis macro also must not be used inside the parameter list in a function call.
strndupais only available if GNU CC is used.
The
strcatfunction is similar tostrcpy, except that the characters from from are concatenated or appended to the end of to, instead of overwriting it. That is, the first character from from overwrites the null character marking the end of to.An equivalent definition for
strcatwould be:char * strcat (char *restrict to, const char *restrict from) { strcpy (to + strlen (to), from); return to; }This function has undefined results if the strings overlap.
The
wcscatfunction is similar towcscpy, except that the characters from wfrom are concatenated or appended to the end of wto, instead of overwriting it. That is, the first character from wfrom overwrites the null character marking the end of wto.An equivalent definition for
wcscatwould be:wchar_t * wcscat (wchar_t *wto, const wchar_t *wfrom) { wcscpy (wto + wcslen (wto), wfrom); return wto; }This function has undefined results if the strings overlap.
Programmers using the strcat or wcscat function (or the
following strncat or wcsncar functions for that matter)
can easily be recognized as lazy and reckless. In almost all situations
the lengths of the participating strings are known (it better should be
since how can one otherwise ensure the allocated size of the buffer is
sufficient?) Or at least, one could know them if one keeps track of the
results of the various function calls. But then it is very inefficient
to use strcat/wcscat. A lot of time is wasted finding the
end of the destination string so that the actual copying can start.
This is a common example:
/* This function concatenates arbitrarily many strings. The last parameter must beNULL. */ char * concat (const char *str, ...) { va_list ap, ap2; size_t total = 1; const char *s; char *result; va_start (ap, str); /* Actuallyva_copy, but this is the name more gcc versions understand. */ __va_copy (ap2, ap); /* Determine how much space we need. */ for (s = str; s != NULL; s = va_arg (ap, const char *)) total += strlen (s); va_end (ap); result = (char *) malloc (total); if (result != NULL) { result[0] = '\0'; /* Copy the strings. */ for (s = str; s != NULL; s = va_arg (ap2, const char *)) strcat (result, s); } va_end (ap2); return result; }
This looks quite simple, especially the second loop where the strings are actually copied. But these innocent lines hide a major performance penalty. Just imagine that ten strings of 100 bytes each have to be concatenated. For the second string we search the already stored 100 bytes for the end of the string so that we can append the next string. For all strings in total the comparisons necessary to find the end of the intermediate results sums up to 5500! If we combine the copying with the search for the allocation we can write this function more efficient:
char *
concat (const char *str, ...)
{
va_list ap;
size_t allocated = 100;
char *result = (char *) malloc (allocated);
if (result != NULL)
{
char *newp;
char *wp;
va_start (ap, str);
wp = result;
for (s = str; s != NULL; s = va_arg (ap, const char *))
{
size_t len = strlen (s);
/* Resize the allocated memory if necessary. */
if (wp + len + 1 > result + allocated)
{
allocated = (allocated + len) * 2;
newp = (char *) realloc (result, allocated);
if (newp == NULL)
{
free (result);
return NULL;
}
wp = newp + (wp - result);
result = newp;
}
wp = mempcpy (wp, s, len);
}
/* Terminate the result string. */
*wp++ = '\0';
/* Resize memory to the optimal size. */
newp = realloc (result, wp - result);
if (newp != NULL)
result = newp;
va_end (ap);
}
return result;
}
With a bit more knowledge about the input strings one could fine-tune
the memory allocation. The difference we are pointing to here is that
we don't use strcat anymore. We always keep track of the length
of the current intermediate result so we can safe us the search for the
end of the string and use mempcpy. Please note that we also
don't use stpcpy which might seem more natural since we handle
with strings. But this is not necessary since we already know the
length of the string and therefore can use the faster memory copying
function. The example would work for wide characters the same way.
Whenever a programmer feels the need to use strcat she or he
should think twice and look through the program whether the code cannot
be rewritten to take advantage of already calculated results. Again: it
is almost always unnecessary to use strcat.
This function is like
strcatexcept that not more than size characters from from are appended to the end of to. A single null character is also always appended to to, so the total allocated size of to must be at least size+ 1bytes longer than its initial length.The
strncatfunction could be implemented like this:char * strncat (char *to, const char *from, size_t size) { to[strlen (to) + size] = '\0'; strncpy (to + strlen (to), from, size); return to; }The behavior of
strncatis undefined if the strings overlap.
This function is like
wcscatexcept that not more than size characters from from are appended to the end of to. A single null character is also always appended to to, so the total allocated size of to must be at least size+ 1bytes longer than its initial length.The
wcsncatfunction could be implemented like this:wchar_t * wcsncat (wchar_t *restrict wto, const wchar_t *restrict wfrom, size_t size) { wto[wcslen (to) + size] = L'\0'; wcsncpy (wto + wcslen (wto), wfrom, size); return wto; }The behavior of
wcsncatis undefined if the strings overlap.
Here is an example showing the use of strncpy and strncat
(the wide character version is equivalent). Notice how, in the call to
strncat, the size parameter is computed to avoid
overflowing the character array buffer.
#include <string.h>
#include <stdio.h>
#define SIZE 10
static char buffer[SIZE];
main ()
{
strncpy (buffer, "hello", SIZE);
puts (buffer);
strncat (buffer, ", world", SIZE - strlen (buffer) - 1);
puts (buffer);
}
The output produced by this program looks like:
hello
hello, wo