strcpy function


strcpy copies a string. This function will copy the bytes stored at the location pointed to by 's2' to the location pointed to by 's1'.


     	s1		s2
	|		|
	V		V
        - - - -		- - - --	
       | | | | |       |a|b|c|\0|
        - - - -		- - - --	
	^ ^		| |
	| |		| |
	 -|-------------  |
	   ---------------


Library:   string.h

Prototype: char strcpy(char *s1, const char *s2);

Syntax:	  
	   char string2[20]="red dwarf";
	   char string1[20]="";
           strcpy(string1, string2);


Notes

Dont forget that strings are terminated with a '\0' so allow space for it...

And strcpy doesn't check that s2 is actually terminated by a \0. If you pass it a char array that isn't property initialized, it will happily keep copying whatever is after s2 into s1.

And strcpy doesn't check the size of s1. If you specify char string1[4]=""; in the example above, it will happily copy "dwarf\0" over the top of whatever happened to be after string1 in memory.

There is a "safe" version called strncpy which takes both the destination and source char pointers, and a maximum length value. It is normally called like this: strncpy(string1, string2, sizeof(string1));. However, it has serious flaws.

A better option is to use strncat after setting the destination string to zero length. e.g. via *s1=0;. For some strange reason, strncat does a much better job than strncpy, always closing with one null.

The smart way to do a string copy is with strlcpy, which  checks the source and destination length (the former via strlen, the later via the sizeof value passed as a parameter). It is not available in string.h, but is easy to implement as follows:

size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
  size_t len = strlen(src);
  if(dstsize) {
    size_t bl = (len < dstsize-1 ? len : dstsize-1);
    ((char*)memcpy(dst, src, bl))[bl] = 0;
  }
  return len; //why not return bl?
}

Note that strlcpy can't figure out the size of dst from inside the function, because that value isn't known at runtime. It must be passed in the dstsize parameter because it is known at compile time when the function is called, but it will be different for each call, or more accurately, for each destination string.

Although the return value of the standard implementation of this is the length of the src string, it makes far more sense to return bl, which is the lengh of the text actually copied.

size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
  size_t len = strlen(src);
  size_t bl=0;
  if(dstsize) {
    bl = (len < dstsize-1 ? len : dstsize-1);
    ((char*)memcpy(dst, src, bl))[bl] = 0;
  }
  return bl; //return characters actually copied
}

There is another way to code the example above. Consider this piece of code.

	main()
	{
	  char *string2="red dwarf";
	  char *string1;

	  string1=string2;
	}

'string2' is now a character pointer (only one byte) that points to a storage location containing "red dwarf" (a string constant). So string1=string2; copies the address of "red dwarf" into 'string1'. This version of the code will execute quicker than strcpy because less data is being moved around the system. On the other hand, if you now modify string2, string1 will also be changed.


example program.

See also:

strtok
strncpy
sprintf
strcat
strings
memcpy Copy data between two memory locations.


Top Master Index Keywords Functions


Martin Leslie