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);
.
char* s1; char s2[15] = "Hello world"; strcpy(s1, s2); |
char s1[5]; char s2[15] = "Hello world"; strcpy(s1, s2); |
(a) | (b) |
char*
does not allocate memory to store the copied C-string.strcpy
function does not require s1 to have a null termination character.
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) |
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; while (*(s++) = *(source++)) ; return dest; } |
(a) | (b) |
<=
rather than <
- the additional iteration copies the null terminator at the end of source to destination.Turning our attention to the while-loop, we see that the loop has a null statement, indicated by the semicolon below the loop. So, it does all the work in the loop test inside the parentheses. We see the same pattern on both sides of the assignment operator. To help understand that pattern, notice the use of the post-increment operator; so, we first use the value in the variable, and then increment the value. Initially, source and dest point to the first character in their respective C-strings; following the increment operation, they point to the second character, and so on until the loop reaches the end of source.
To get the individual characters, we must dereference each C-string. The inner or grouping parentheses are necessary because the dereference operator has higher precedence than the auto-increment operator. Without the parentheses, the increment operator would increment the character (e.g., 'A' + 1 = 'B') rather than the pointer. So, the loop extracts a character from source and assigns it to dest. It then increments both pointers to the next characters in the strings and repeats the copy. The loop continues until it copies the '\0' at the end of source to dest. The '\0' is the character-equivalent of 0, which ends the loop (see Boolean Type and Values).