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 ex- plicitly identified in this manual. In addition to functions in this section, there are
a few others like sprintf (see Section 17.12.7 [Formatted Output Functions], page 470) andscanf(seeSection 17.14.8 [Formatted Input Functions], page 495).
Function
void *memcpy (void *restrictto, const void *restrictfrom, size_tsize)
Thememcpyfunction copiessize bytes from the object beginning atfrom into the object beginning atto. The behavior of this function is undefined if the two arraystoandfromoverlap; usememmoveinstead if overlapping is possible. The value returned bymemcpyis the value ofto.
Here is an example of how you might usememcpyto copy the contents of an array:
struct foo *oldarray, *newarray; int arraysize;
...
memcpy (new, old, arraysize * sizeof (struct foo));
Function
wchar_t *wmemcpy (wchar_t *restrictwto, const wchar_t *restructwfrom, size_tsize)
Thewmemcpyfunction copiessize wide characters from the object beginning at wfrom into the object beginning at wto. The behavior of this function is undefined if the two arrayswto andwfromoverlap; usewmemmoveinstead if overlapping is possible.
The following is one possible implementation ofwmemcpy, but there are also other 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 bywmemcpyis the value ofwto. This function was introduced in Amendment 1 toISOC90.
Function
void *mempcpy (void *restrictto, const void *restrictfrom, size_tsize)
The mempcpyfunction is nearly identical to thememcpyfunction. It copies
size bytes from the object beginning atfrominto the object pointed to byto. But instead of returning the value ofto, it returns a pointer to the byte following the last written byte in the object beginning at to—the value is((void *) ((char *)to+size)).
This function is useful in situations where a number of objects will be copied to consecutive memory positions:
void *
Chapter 5: String and Array Utilities 95
{
void *result = malloc (s1 + s2); if (result != NULL)
mempcpy (mempcpy (result, o1, s1), o2, s2); return result;
}
This function is aGNUextension.
Function
wchar_t *wmempcpy (wchar_t *restrictwto, const wchar_t *restrictwfrom, size_tsize)
Thewmempcpyfunction is nearly identical to thewmemcpyfunction. It copies
sizewide characters from the object beginning atwfrominto the object pointed to bywto. 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 atwto—the value iswto+size.
This function is useful in situations where a number of objects will be copied to consecutive memory positions.
The following is one possible implementation ofwmemcpy, but there are also other 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 aGNUextension.
Function
void *memmove (void *to, const void *from, size_t size)
memmovecopies thesize bytes atfrominto thesize bytes atto, 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 atfrom, including those bytes that also belong to the block atto.
The value returned bymemmoveis the value ofto.
Function
wchar_t *wmemmove (wchar *wto, const wchar_t *wfrom, size_tsize)
wmemmovecopies thesize wide characters atwfrom into thesize wide char- acters atwto, even if those two blocks of space overlap. In the case of overlap,
memmove is careful to copy the original values of the wide characters in the block atwfrom, including those wide characters that also belong to the block at
wto.
The following is one possible implementation ofwmemcpy, but there are also other 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 bywmemmoveis the value ofwto. This function is aGNUextension.
Function
void *memccpy (void *restrictto, const void *restrictfrom, intc, size_tsize)
This function copies no more thansizebytes fromfromtoto, stopping if a byte matchingc is found. The return value is a pointer intotoone byte past where
c was copied, or a null pointer if no byte matchingc appeared in the firstsize
bytes offrom.
Function
void *memset (void *block, intc, size_tsize)
This function copies the value of c (converted to an unsigned char) into each of the firstsize bytes of the object beginning atblock. It returns the value ofblock.
Function
wchar_t *wmemset (wchar_t *block, wchar_twc, size_tsize)
This function copies the value ofwc into each of the firstsize wide characters of the object beginning atblock. It returns the value ofblock.
Function
char *strcpy (char *restrictto, const char *restrictfrom)
This copies characters from the stringfrom(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 ofto.
Function
wchar_t *wcscpy (wchar_t *restrictwto, const wchar_t *restrictwfrom)
This copies wide characters from the stringwfrom(up to and including the ter- minating null wide character) into the stringwto. Likewmemcpy, this function has undefined results if the strings overlap. The return value is the value ofwto.
Function
char *strncpy (char *restrictto, const char *restrictfrom, size_tsize)
This function is similar to strcpybut always copies exactly size characters intoto.
If the length offromis more thansize, thenstrncpycopies just the firstsize
Chapter 5: String and Array Utilities 97 If the length of from is less thansize, thenstrncpycopies all offrom, fol- lowed by enough null characters to add up tosizecharacters in all. This behavior is rarely useful, but it is specified by theISOC standard.
The behavior ofstrncpyis undefined if the strings overlap.
Using strncpy as opposed to strcpy is a way to avoid bugs relating to writing past the end of the allocated space forto. However, it can also make your program much slower in one common case: copying a string that 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.
Function
wchar_t *wcsncpy (wchar_t *restrictwto, const wchar_t *restrictwfrom, size_tsize)
This function is similar towcscpybut always copies exactlysizewide charac- ters intowto.
If the length ofwfromis more thansize, thenwcsncpycopies just the firstsize
wide characters. Note that in this case there is no null terminator written into
wto.
If the length of wfrom is less thansize, then wcsncpy copies all ofwfrom, followed by enough null wide characters to add up tosize wide characters in all. This behavior is rarely useful, but it is specified by theISOC standard. The behavior ofwcsncpyis undefined if the strings overlap.
Usingwcsncpyas opposed towcscpyis a way to avoid bugs relating to writ- ing past the end of the allocated space forwto. However, it can also make your program much slower in one common case: copying a string that 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.
Function
char *strdup (const char *s)
This function copies the null-terminated string s into a newly allocated string. The string is allocated using malloc(seeSection 3.2.2 [Unconstrained Allo- cation], page 42). Ifmalloccannot allocate space for the new string,strdup
returns a null pointer. Otherwise, it returns a pointer to the new string.
Function
wchar_t *wcsdup (const wchar_t *ws)
This function copies the null-terminated wide-character stringws into a newly allocated string. The string is allocated usingmalloc(seeSection 3.2.2 [Un- constrained Allocation], page 42). 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 aGNUextension.
Function
char *strndup (const char *s, size_tsize)
This function is similar tostrdupbut always copies at most size characters into the newly allocated string.
If the length ofsis more thansize, thenstrndupcopies just the firstsizechar- acters and adds a closing null terminator. Otherwise, all characters are copied and the string is terminated.
This function is different tostrncpyin that it always terminates the destina- tion string.
strndupis aGNUextension.
Function
char *stpcpy (char *restrictto, const char *restrictfrom)
This function is likestrcpy, except that it returns a pointer to the end of the string to (that is, the address of the terminating null character to + 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 theISOorPOSIXstandards, and is not customary on Unix systems, but we did not invent it either. Perhaps it comes fromMS-DOS. Its behavior is undefined if the strings overlap. The function is declared in ‘string.h’.
Function
wchar_t *wcpcpy (wchar_t *restrictwto, const wchar_t *restrictwfrom)
This function is likewcscpy, except that it returns a pointer to the end of the stringwto(that is, the address of the terminating null characterwto + strlen (wfrom)) rather than the beginning.
This function is not part ofISOorPOSIXbut was found useful while developing theGNUC Library itself.
The behavior ofwcpcpyis undefined if the strings overlap.
Chapter 5: String and Array Utilities 99 Function
char *stpncpy (char *restrictto, const char *restrictfrom, size_tsize)
This function is similar to stpcpybut copies always exactly size characters intoto.
If the length offromis more thensize, thenstpncpycopies just the firstsize
characters and returns a pointer to the character directly following the one that was copied last. In this case, there is no null terminator written intoto.
If the length of from is less thansize, thenstpncpycopies all offrom, fol- lowed by enough null characters to add up tosizecharacters in all. This behavior is rarely useful, but it is implemented to be useful in contexts where this behav- ior of thestrncpyis used.stpncpyreturns a pointer to thefirstwritten null character.
This function is not part ofISOorPOSIXbut was found useful while developing
theGNUC Library itself.
Its behavior is undefined if the strings overlap. The function is declared in ‘string.h’.
Function
wchar_t *wcpncpy (wchar_t *restrictwto, const wchar_t *restrictwfrom, size_tsize)
This function is similar towcpcpybut copies always exactlywsize characters intowto.
If the length ofwfromis more thensize, thenwcpncpycopies just the firstsize
wide characters and returns a pointer to the wide character directly following the last nonnull wide character which was copied last. Note that in this case there is no null terminator written intowto.
If the length of wfrom is less thansize, then wcpncpy copies all ofwfrom, 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 thefirst
written null character.
This function is not part ofISOorPOSIXbut was found useful while developing theGNUC Library itself.
Its behavior is undefined if the strings overlap.
wcpncpyis aGNUextension and is declared in ‘wchar.h’.
Macro
char *strdupa (const char *s)
This macro is similar tostrdupbut allocates the new string using alloca
instead ofmalloc(seeSection 3.2.5 [Automatic Storage with Variable Size], page 71). This means that 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 using mallocwould be much 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; }
strtokmust be passed a writeable string. Passing a const string, such aspath
in the above example, would be invalid. Also, usingstrdupadirectly would also cause conflict due to the use of allocainstrdupa(seeSection 3.2.5 [Automatic Storage with Variable Size], page 71).
This function is only available ifGNUCC is used.
Macro
char *strndupa (const char *s, size_tsize)
This function is similar tostrndup, but like strdupait allocates the new string usingalloca(seeSection 3.2.5 [Automatic Storage with Variable Size], page 71). The same advantages and limitations of strdupa are valid for
strndupatoo.
This function is implemented only as a macro, just like strdupa. Just as
strdupa, this macro also must not be used inside the parameter list in a func- tion call.
strndupais only available ifGNU CCis used.
Function
char *strcat (char *restrictto, const char *restrictfrom)
The strcat function is similar tostrcpy, except that the characters from
from are concatenated or appended to the end ofto, instead of overwriting it. The first character fromfrom overwrites the null character marking the end of
to.
An equivalent definition forstrcatwould be
Chapter 5: String and Array Utilities 101
strcat (char *restrict to, const char *restrict from) {
strcpy (to + strlen (to), from); return to;
}
This function has undefined results if the strings overlap.
Function
wchar_t *wcscat (wchar_t *restrictwto, const wchar_t *restrictwfrom)
The wcscat function is similar towcscpy, except that the characters from
wfrom are concatenated or appended to the end ofwto, instead of overwriting it. The first character fromwfromoverwrites the null character marking the end ofwto.
An equivalent definition forwcscatwould 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 (since otherwise you cannot ensure that the allocated size of the buffer is sufficient). Or at least you could know them if you keep track of the results of the various function calls. But then it is very inefficient to usestrcat/wcscat. Much 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. */
/* 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 add up to 5500! If we combine the copying with the search for the allocation, we can write this function more efficiently:
char *
concat (const char *str, ...) {
va_list ap;
size_t allocated = 100;
char *result = (char *) malloc (allocated); char *wp;
if (allocated != NULL) {
char *newp;
va_start (ap, atr);
wp = result;
Chapter 5: String and Array Utilities 103
{
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 mem- ory allocation. The difference we are pointing to here is that we don’t usestrcat
anymore. We always keep track of the length of the current intermediate result so we can save the search for the end of the string and usemempcpy. We also don’t usestpcpy, which might seem more natural since we handle 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