Talk C chestnuts together (60th back: C language instance-string replication)
Hello, everyone. In the previous article, we talked about the string overview example. This example is string replication. Idle
The words are now in turn. Let's talk C chestnuts together!
The readers provided us with the string copy function in the standard library of C language. We only need to include the string. h header file to use
String Copy function. The standard library provides four string replication functions: strcpy, strncpy, memcpy, and memmove. Next we
This section describes their usage and precautions.
Strcpy function prototype: char * strcpy (char * s1, const char * s2) strcpy function usage: It copies the content in s2 to s1 and returns s1.strcpy. Note: if the content in s2 is too large to exceed the capacity of s1, the content in memory after s1 will be overwritten.
The following strings are defined in the program:
char s0[SIZE] = string;char s1[SIZE]=str-1;char s2[SIZE+3]=str-2and123;char s3[SIZE] = {'A','B'};// other element of s3 is char s4[] = {'A','B'}; // there is loss of at the end of string
The memory address and content of these strings are displayed before strcpy and after strcpy. The results are as follows:
addr: 0xbfb08a39 | s0 : stringaddr: 0xbfb08a41 | s1 : str-1addr: 0xbfb08a51 | s2 : str-2and123addr: 0xbfb08a49 | s3 : ABaddr: 0xbfb08a39 | s4 : ABstring ----- after running strcpy(s1,s3) -----addr: 0xbfb08a39 | s0 : stringaddr: 0xbfb08a41 | s1 : ABaddr: 0xbfb08a51 | s2 : str-2and123addr: 0xbfb08a49 | s3 : ABaddr: 0xbfb08a39 | s4 : ABstring ----- after running strcpy(s1,s2) -----addr: 0xbfb08a39 | s0 : stringaddr: 0xbfb08a41 | s1 : str-2and123addr: 0xbfb08a51 | s2 : str-2and123addr: 0xbfb08a49 | s3 : 123addr: 0xbfb08a39 | s4 : ABstring
From the running results, we can see that when the content of s3 is copied to s1 using strcpy (s1, s3), the content of s1 is changed to that of s3
The contents of the other strings remain unchanged.
When the content of s2 is copied to s1 using strcpy (s1, s2), the content of s1 is changed to s2, and the content of s3 is changed.
Let's take a look at the proximity between s1 and s3. It must be that the memory after s1 is "contaminated" during the replication process, so the s3 content
If it is modified, s3 is lying down. To give you a clearer understanding of how s3 is shot
Row analysis:
Address in memory:0xbfb08a4 1 2 3 4 5 6 7 8 9 a B c d e f
Value in the address:S t r-2 a n d 1 2 3
Let's take a look at the s1 address starting from 0xbfb08a41, which occupies 8 bytes, that is, it ends at 0xbfb08a48, but execute the strcpy operation
11 characters are copied, which obviously exceeds the eight bytes occupied by s1. Therefore, it forcibly occupies the content of the last three bytes,
The space of the next three bytes is allocated to s3 by the system. Although s3 has the space of the three bytes, the content in the space has been forcibly occupied by s1.
. S3 is lying down like this.
Strncpy function prototype: char * strcpy (char * s1, const char * s2, size_t n) strncpy function usage: It copies n characters in s2 to s1, note: If the number of characters in s1.strncpy is greater than n, only n characters are copied to S1. a small string tail is not added after n characters. If the number of characters in s2 is less than n, only all characters in s2 are copied. If not, use null characters: to add until n characters. In our general experience, we set the n value to be smaller than 1 For s1 during replication, and manually add a small tail to s1. If the value of n is greater than the capacity of s1, it is the same as that of strcpy. Strncpy is introduced to control the copy content through n and avoid defects similar to strcpy replication. Therefore, we need to use n card. The key point is to win the game, haha.
Let's take a practical example to illustrate that the program also uses the defined string, and displays
The memory address and content of these strings are displayed. The result is as follows:
Addr: 0xbfed56a9 | s0: string // execute strncpy before each string value addr: 0xbfed56b1 | s1: str-1addr: 0xbfed56c1 | s2: str-2and123addr: 0xbfed56b9 | s3: ABaddr: 0xbfed56a9 | s4: ABstring ----- after running strncpy (s1, s3, SIZE) ----- addr: 0xbfed56a9 | s0: stringaddr: 0xbfed56b1 | s1: AB // s3 contains less than SIZE, so there are small tail addr: 0xbfed56c1 | s2: str-2and123addr: 0xbfed56b9 | s3: ABaddr: 0xbfed56a9 | s4: ABstring ----- after running strncpy (s1, s2, SIZE) ----- addr: 0xbfed56a9 | s0: stringaddr: 0xbfed56b1 | s1: str-2andAB // 8 characters are copied from s2, but no small tail addr: 0xbfed56c1 | s2: str-2and123addr: 0xbfed56b9 | s3: ABaddr: 0xbfed56a9 | s4: ABstring ----- after running strncpy (s1, s2, SIZE-1) ----- addr: 0xbfed56a9 | s0: stringaddr: 0xbfed56b1 | s1: str-2an // 7 characters are copied from s2, manually add a small tail addr: 0xbfed56c1 | s2: str-2and123addr: 0xbfed56b9 | s3: ABaddr: 0xbfed56a9 | s4: ABstring ----- after running strncpy (s1, s2, SIZE + 3) ----- addr: 0xbfed56a9 | s0: stringaddr: 0xbfed56b1 | s1: 0xbfed56a9 | s4: ABstring
We performed four replication operations using strncpy (s1, s2, n:
During the first copy, s2 contains less than n characters, s1 and s2 share the same content, and a small tail is added to the content in S1. During the second copy, the number of characters in s2 is greater than n, and the first n characters in s1 and s2 are the same. Because the content in s1 does not have a small tail, it also displays the content in s3, because s1 is adjacent to the s3 address, and the string in s3 has a small tail. You can use the method of analyzing the addresses in the memory just now. I will not go into details. During the third copy, the number of characters in s2 is greater than n, and the content of the first seven characters in s1 and s2 is the same. We manually add a small tail to s1, which is recommended. The value of n in the fourth copy is greater than the capacity of s1. The content of s1 and s2 is the same, but s1 pollutes other memory spaces, which is the same as that of strcpy, I have already analyzed it. I will not detail it here.
Next let's talk about the memcpy function:
Memcpy function prototype: void * memcpy (char * s1, const char * s2, size_t n) memcpy function usage: It copies n characters in s2 to s1, note: s1.memcpy is the same as strncpy. Please refer to the content of strncpy above. Haha!
The usage of memcpy is similar to that of strncpy, so we will not give an example. You can refer to the strncpy example above.
Strcpy, strncpy, and memcpy both have a common drawback: if the memory space of s1 and s2 overlaps, use these
The function will have unexpected consequences, which will lay a "mine" for the program, once the outbreak is very serious. It's not certain that you want to dig this Ray.
Experience is hard to find out. Memmove is provided for this standard library. It can avoid this disadvantage.
Memmove function prototype: void * memmove (char * s1, const char * s2, size_t n) memmove function usage: It copies n characters in s2 to s1, note for returning s1.memmove: it is the same as strncpy. Please refer to the content of strncpy above. Haha! If s1 and s2 have overlapping parts, it can be well processed.
Let's take a practical example to illustrate that the program also uses the defined string and runs the four copy functions to display these words separately.
The memory address of the string and the content of the string are as follows:
----- After running memmove (s1, s3, SIZE) ----- addr: 0xbff8aca9 | s0: stringaddr: 0xbff8acb1 | s1: AB // This is a normal copy operation and there is no problem with addr: 0xbff8acc1 | s2: str-2and123addr: 0xbff8acb9 | s3: ABaddr: 0xbff8aca9 | s4: ABstring ----- after running strcpy (s2, s2 + 1) ----- addr: 0xbff8acc1 | s2: tr-2and123 // memory overlaps during replication, results are abnormal ----- after running strncpy (s2, s2 + 1, SIZE) ----- addr: 0xbff8acc1 | s2: tr-2and1123 // memory overlaps during replication, the result is normal ----- after running memcpy (s2, s2 + 1, SIZE) ----- addr: 0xbff8acc1 | s2: tr-2and1123 // The Memory overlaps during replication, and the result is normal ----- after running memmove (s2, s2 + 1, SIZE) ----- addr: 0xbff8acc1 | s2: tr-2and1123 // The Memory overlaps during replication and the result is normal
Compared with the program running result, we can see that if the memory overlaps when the string is copied, only the result of strcpy replication is abnormal.
The result of several other string copy functions is normal. In fact, the new C library updates strncpy and momcpy
We can also perform replication like memmove, but there is no official information to describe, So we follow the old standards to introduce
Describes the four string copy functions.
Today, we have a lot of content. At last, we will summarize the four copy functions:
When strcpy is copied, it copies the null character behind the string, that is, the small tail we call. strncpy and memcpy won't. Strcpy usually performs operations on strings with a small tail. strncpy and memcpy can perform operations regardless of whether the string has a small tail. the copy function starting with str can only replicate strings. However, the copy function starting with mem can replicate strings and other types of data, for example, you can define the struct type data. Therefore, it is more widely used.
After our introduction to the string replication function, do you think the standard library is somewhat unreliable. In fact, the standard library is still very good
Only for historical reasons. For example, all kinds of popular Internet terms are not in the dictionary.
To the dictionary. The standard library is similar to the dictionary we use. The function is first available and then collected to the standard library.
Some library functions have disadvantages, but they have been widely used. Therefore, we need to collect them first and then provide some improved library functions.
I organized all the examples into a file and added detailed comments. No code is written in the text to avoid confusion,
The detailed code is stored in my resources. You can click here to download and use it.
Let's talk about the example of string replication. I want to know what examples will be provided later, and I will try again.