8.2.2.2. strcpy

Time: 00:01:06 | Download: Large, Large (CC), Small | Streaming, Streaming (CC) | Slides: PDF, PPTX

Given two C-strings defined as char* s1 and char* s2, the statement s1 = s2; compiles without error. So, copying a C-string with the assignment operator appears straightforward. However, when used with pointer operands, including C-strings, the assignment operator copies the address in the right-hand operand to the left-hand operand - see Figure 1(b), which illustrates pointer assignment. Specifically, the assignment operator does not copy the string text to which the pointer points. Copying a string is still a necessary operation, and so the C-string library provides a function to perform the task: strcpy(s1, s2);.

strcpy: String-Copy

Two C-strings represented as sequences of squares. String s1 stores the characters 'EXAMPLE', and string s2 stores 'HELLO'. The picture illustrates the copy operation as 'H' in s2 replacing the first 'E' in s1; 'E' in s2 replacing 'X' in s1, until '\0' in s2 replaces the 'L' in s1.

strcpy(s1, s2)

Copying C-Strings. The source (the second argument) is copied character-by-character (including the null termination character) to the destination (the first argument). If the source is shorter than the destination, as in this example, the characters following the copied null terminator become irrelevant. For example, the null terminator in s2[5] overwrites the 'L' in s1[5], making the 'E' and the null terminator at positions 6 and 7 in s1 irrelevant because after the copy operation, s1 logically ends with the null terminator at position 5. The strcpy function is unusual in that it is not necessary to null-terminate the destination, s1 in the example, before calling the function.
Header File:
#include <cstring>
Standard Prototype:
char* strcpy(char* destination, const char* source);
Please see strcpy for more information
Microsoft Prototype:
errno_t strcpy_s(char* dest, size_t size, const char* source);
Returns 0 when the copy succeeds; returns non-0 on failure.
Please see strcpy_s for more information

strcpy Examples

char* s1;
char s2[15] = "Hello world";
strcpy(s1, s2);
char s1[5];
char s2[15] = "Hello world";
strcpy(s1, s2);
(a)(b)
Common strcpy errors.
  1. char* does not allocate memory to store the copied C-string.
  2. Although s1 is defined as an array, it's too small to hold all of the s2 characters.
The strcpy function does not require s1 to be null-terminated before the copy operation.

 

Standard Version Microsoft Version
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
	char s1[100] = "EXAMPLE";
	char* s2 = "HELLO";

	cout << strcpy(s1, s2) << endl;
	cout << s1 << endl;

	return 0;
}
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
	char s1[100] = "EXAMPLE";
	char* s2 = "HELLO";

	cout << strcpy_s(s1, 100, s2) << endl;
	cout << s1 << endl;

	return 0;
}
 
Output:
HELLO
HELLO
0
HELLO
(a)(b)
The strcpy function. The string-copy function copies its second argument to its first. Both arguments are passed by pointer, but the second argument is const and can't be modified, and the first must refer to memory large enough to store the copied string. The standard and Microsoft versions return the copied string through the first argument.
  1. The standard version returns s1 as the return value, making the copied C-string available a second way.
  2. The Microsoft version returns an error condition: 0 when the function succeeds and non-0 when it fails.

Possible strcpy Implementations

char* strcpy(char* dest, const char* source)
{
	for (size_t i = 0; i <= strlen(source); i++)
		dest[i] = source[i];

	return dest;
}

 
char* strcpy(char* dest, const char* source)
{
	char* s = dest;			// (i)

	while (*(s++) = *(source++))	// (ii)
		;

	return dest;			// (iii)
}
(a)(b)
Implementations of the standard strcpy function.
  1. A straightforward implementation using a for-loop and array notation (i.e., the index operator []) to copy the contents of one C-string array to another. Notice the use of <= rather than < - the additional iteration copies the null terminator at the end of source to dest.
  2. The compiler translates the first two statements into just a few, efficient machine instructions, making this an efficient implementation of the strcpy function.
    1. The assignment operation preserves the address stored in dest for statement (iii), allowing the loop to increment s without altering dest.
    2. The placement of the semicolon ending the while-loop denotes a beneficial null statement, so the character copy occurs inside the loop's test. The loop begins with the first character of each string, advances each pointer one character at a time by incrementing the addresses in each pointer, and copies the characters using the assignment operator. Both assignment operands follow the same pattern: the dereference operator accesses a character, then the post-increment operator advances the pointer to the next character.
    3. The return statement is common to all strcpy implementations, neither improving nor degrading efficiency.