Syntax:
Understanding strcpy():
The sole purpose of the strcpy() function is to copy a string from source to destination. Now, lets us look at the above syntax of strcpy() function. The strcpy() function is capable of accepting two parameters –
- char * destination
- const char * source
The source is a constant here to ensure that the strcpy() function cannot change the source string. The strcpy() function copies all the characters (including the NULL character at the end of the string) from the source string to the destination. Once the copy operation is complete from source to destination, the strcpy() function returns the address of the destination back to the caller function.
The important point to notice here is, the strcpy() function does not append the source string with the destination string. It rather replaces the content of the destination with the content of the source string.
Also, the strcpy() function does not perform any checks to ensure that the size of the destination is more than the source string, it is completely the responsibility of the programmer.
Examples:
Now, we will see several examples to understand the strcpy() function:
- strcpy() – Normal Operation (example1.c)
- strcpy() – Case-1 (example2.c)
- strcpy() – Case-2 (example3.c)
- strcpy() – Case-3 (example4.c)
- strcpy() – User Defined Version (example5.c)
- strcpy() – User Defined Version Optimized (example6.c)
strcpy() – Normal Operation (example1.c):
This example program shows how to perform a normal string copy operation using the strcpy() function in the C programming language. Please note that the length of the destination string is 30 (char destination_str[30]; ), which is greater than the length of the source string (length is 18 including the NULL character) so that the destination can accommodate all the characters from the source string.
#include <string.h>
int main()
{
char source_str[] = "www.linuxhint.com";
char destination_str[30];
printf("Before calling strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
strcpy(destination_str, source_str);
printf("After executing strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
return 0;
}
strcpy() – Case-1 (example2.c):
The intent of this example program is to clearly explain what happens when the length of the destination string is less than the length of the source string. In such cases, the destination location will not have enough spaces/bytes to accommodate all the characters (including NULL character) from the source string. Two things, you should always keep in mind:
- The strcpy() function will not check if the destination has enough space.
- This could be dangerous in embedded software because the strcpy() will replace the memory area beyond the destination’s boundary.
Let us look at the example program. We have declared source_str and initialized it to “www.linuxhint.com”, which will take 18 bytes in memory to store, including the Null character at the end of the string. Then, we have declared another character array i.e. destination_str with the size of only 5. So, the destination_str cannot hold the source string with a total size of 18 bytes.
But, still, we are calling the strcpy() function to copy the source string to destination string. From the below output, we can see the strcpy() did not complain at all. In this case, the strcpy() function will start copying the character from the source string (until it finds the NULL character in the source string) to the destination address (even though destination boundary exceeds). That means the strcpy() function does not do any boundary checking for destination array. Eventually, the strcpy() function will overwrite the memory addresses which are not allocated to the destination array. This is why the strcpy() function will end up overwriting the memory locations which might be allocated to a different variable.
In this example, we can see from the below output, that the strcpy() function overwrites the source string itself. Programmers should always be careful with such behavior.
#include <string.h>
int main()
{
char source_str[] = "www.linuxhint.com";
char destination_str[5];
printf("Before calling strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
strcpy(destination_str, source_str);
printf("After executing strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
//printf("Source Address = %u (0x%x)\n", &source_str[0], &source_str[0]);
//printf("Destination Address = %u (0x%x)\n", &destination_str[0], &destination_str[0]);
return 0;
}
strcpy() – Case-2 (example3.c):
This program illustrates the situation when the destination string size is greater than the source string size and destination string is already initialized with some value. In this example, we have initialized:
- source_str to “www.linuxhint.com” [size = 17+1 = 18]
- destination_str to “I_AM_A_DESTINATION_STRING” [size = 25+1 = 26]
The strcpy() function will copy all the 17 characters and the NULL character from the source string to the destination string. But, it will not replace/change the remaining bytes (Byte 19 to 26, one based) in the destination array. We have used for loop to iterate over the destination array and print the whole array to prove that the bytes-19 to 26 are unchanged in the destination array. That is why we see the last output as:
#include <string.h>
/* This program illustrates the situation when :
destination string size > source string size
and we execute strcpy() function to copy the
source string to destination.
Note: The destination string size should always
be greater than or equal to the source string.
*/
int main()
{
char source_str[] = "www.linuxhint.com";
char destination_str[26] = "I_AM_A_DESTINATION_STRING";
printf("Before calling strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
strcpy(destination_str, source_str);
printf("After executing strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
/* print destination string using for loop*/
printf("Print the destination string char by char : \n\n");
printf("\tDestination String = ");
for(int i=0; i<25;i++)
{
printf("%c", destination_str[i]);
}
printf("\n\n");
return 0;
}
strcpy() – Case-3 (example4.c):
We have considered this program as an example to show that we should never call strcpy() with a string literal as the destination. This will cause undefined behavior and eventually, the program will crash.
#include <string.h>
int main()
{
char source_str[] = "www.linuxhint.com";
printf("Before calling strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
/* Never call strcpy() with string literal as destination.
The program will crash.
*/
strcpy("destination_str", source_str);
printf("After executing strcpy() function : \n\n");
printf("\tSource String = %s\n", source_str);
return 0;
}
strcpy() – User Defined Version (example5.c):
In this example program, we have shown how to write a user-defined version of strcpy() function.
char * strcpy_user_defined(char *dest, const char * src);
/* User defined version of strcpy() function */
char * strcpy_user_defined(char *dest, const char * src)
{
char * dest_backup = dest;
while(*src != '\0') /* Iterate until '\0' is found.*/
{
*dest = *src; /* Copy source char to destination */
src++; /* Increment source pointer */
dest++; /* Increment destination pointer */
}
*dest = '\0'; /* Insert '\0' in destination explicitly*/
return dest_backup;
}
int main()
{
char source_str[] = "www.linuxhint.com";
char destination_str[30];
printf("Before calling user defined string copy function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
/* Calling user defined string copy function */
strcpy_user_defined(destination_str, source_str);
printf("After executing user defined string copy function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
return 0;
}
strcpy() – User Defined Version Optimized (example6.c):
Now, in this example program, we are going to optimize the user-defined version of strcpy().
char * strcpy_user_defined(char *dest, const char * src);
/* Optimized version of user defined strcpy() function */
char * strcpy_user_defined(char *dest, const char * src)
{
char * dest_backup = dest;
while(*dest++ = *src++)
;
return dest_backup;
}
int main()
{
char source_str[] = "www.linuxhint.com";
char destination_str[30];
printf("Before calling user defined string copy function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
/* Calling user defined string copy function */
strcpy_user_defined(destination_str, source_str);
printf("After executing user defined string copy function : \n\n");
printf("\tSource String = %s\n", source_str);
printf("\tDestination String = %s\n\n", destination_str);
return 0;
}
Conclusion:
The strcpy() function is a very popular and handy library function to perform the string copy operation in the C programming language. This is mainly used to copy the string from one location to another location. However, we want to reiterate the fact that the strcpy() function does not do the boundary checking for the destination array, which could lead to a serious software bug if ignored. It is always the responsibility of the programmer to make sure the destination array has enough space to hold all the characters from source string including the NULL character.