Hello, everyone. I'm safe and sound.
catalogue
1, Introduction to common string library functions
Implementation of strlen by user-defined function simulation
Implementation of strcpy by user-defined function simulation
Implementation of strcat by user-defined function simulation
Implementation of strcmp by user-defined function simulation
Implementation of STR by user-defined function simulation
2, Character classification function
3, Common memory operation functions
Implementation of memcpy by user-defined function simulation
Implementation of memmove by user-defined function simulation
4, Meet Enron meet you, not negative code, not negative Qing.
preface:
I was in a bad state some time ago, so I haven't updated it for 24 days. When I turned on my mobile phone, I didn't reply in time. I'm going back again and again these days. I'm really sorry. Thank you for your support and company. Now I'm starting to catch up slowly and come on together.
1, Introduction to common string library functions
The operation and processing of characters and strings in C language is very frequent, but C language itself has no string type, so the strings in C language are usually placed in constant strings or character arrays;
String constants apply to string functions that do not modify it.
Key points of this chapter:
Find string length
- strlen
String library function with unlimited length
- strcpy
- strcat
- strcmp
String library function with limited length
- strncpy
- strncat
- strncmp
String lookup
- strstr
- strtok
Error message report
- strerror
Character operation library function
Memory operation Library
- memcpy
- memmove
- memset
- memcmp
be careful:
Unlimited length means that it is appended to '\ 0', which has nothing to do with the length;
Limited length means that it is related to length. It may not be easy to understand. Don't worry. You'll understand when you see the back.
1,strlen()
Function prototype:
Function function:
Find the length of the string
Note: the return value type is size_t. This size_ What exactly is t?
Actually size_t is designed for the return value of sizeof operator, which can be considered as size_t is the well-known unsigned int. because it is for length, it will certainly not be negative. Therefore, unsigned integer is used, but it is also prone to bug s. Please see the following code:
Interpret the following code. What is the output result
#include<stdio.h> #include<string.h> int main() { if (strlen("abc") - strlen("abcdef") > 0) printf(">"); else printf("<="); return 0; }
Yes, the answer is to output ">", why? 3 - 6 = - 3 duck, what's going on?
This is because the return value of strlen is size_t. It's an unsigned number, so if you subtract two unsigned numbers, the answer must be an unsigned number. If you still don't understand, you can see this article and it's very clear.
Deep analysis of data storage in memoryhttps://bit-runout.blog.csdn.net/article/details/121576136 How to modify it?
Scheme 1: forced type conversion
#include<stdio.h> #include<string.h> int main() { if ((int)strlen("abc") - (int)strlen("abcdef") > 0 ) printf(">"); else printf("<="); return 0; }
Scheme 2: direct comparison
#include<stdio.h> #include<string.h> int main() { if (strlen("abc") > strlen("abcdef")) printf(">"); else printf("<="); return 0; }
be careful:
- The string ends with '\ 0'. strlen returns the number of characters before '\ 0' in the string (excluding '\ 0');
- The string pointed to in the parameter must end with '\ 0';
- Note that the return value of the strlen function is size_t type, which belongs to unsigned type (especially error prone)
Code example:
#include<stdio.h> #include<string> int main() { int len = strlen("abcdef"); printf("%d\n", len); return 0; }
Implementation of strlen by user-defined function simulation
- Counter method
- Recursive method
- Pointer pointer
Method 1: counter method
int my_strlen(const char* str) { assert(str);//Assertion str is not null int count = 0; while (*str != '\0') { count++; str++; } return count; }
Method 2: recursive method
int my_strlen(const char* str) { assert(str);//Assertion str is not null //Find boundary if (*str == '\0') { return 0; } int count = my_strlen(str + 1); //Note that str + + and str+1 are different concepts count++; return count; }
It should be noted here that str + + and str+1 are not the same concept. str + + is used first and then + +. This problem can be written in the form of + + str and used first and then + +.
Method 3: pointer pointer
Pointer - pointer actually represents the number of elements between two pointers. Note that there are not a few bytes in the middle.
int my_strlen(const char* str) { assert(str); const char* cur = str; while (*cur != '\0') { cur++; } return cur - str; }
2,strcpy()
Function prototype:
Function function:
Copy the source string to the target string and return the address of the first element of the target string.
Interpret the following codes:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; char arr2[20] = { 0 }; printf("%s\n", strcpy(arr2, arr1)); return 0; }
This problem is to copy the string arr2 # to the string arr1, and return the address of the first element of arrr2 (the address of the first element of the target string). Therefore, the output of the above code is abcdef. The question here is whether the '\ 0' in the string arr1 will be copied to the string arr2. Therefore, the following code is used to verify this problem:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; char arr2[20] = "XXXXXXXXXX"; printf("%s\n", strcpy(arr2, arr1)); return 0; }
First, when the string arr1 ¢ has not been copied to arr2 ¢ yet, the data they store is as follows:
After strcpy(arr2, arr1) is executed, the data stored in arr2 is as follows:
It can be seen that when copying the string arr1 (source string) to the string arr2 (target string), the '\ 0' at the end of the source string will be automatically copied, and the address of the starting position of the target string will be returned.
Another problem here is: if '\ 0' is not added at the end of the source string (this is demonstrated in the form of character array, and '\ 0' will be automatically filled at the end of the normal string), please see the following code:
#include<stdio.h> #include<string.h> int main() { char arr1[] = { 'a','b','c','d','e','f' }; char arr2[20] = "XXXXXXXXXX"; printf("%s\n", strcpy(arr2, arr1)); return 0; }
Code execution result:
Therefore, it should be noted that if you want to copy the source string to the target string, you must ensure that the source string contains' \ 0 ', otherwise the copy will fail.
Therefore, you should pay attention to the following points when using strcpy to copy strings:
- The source string must end with '\ 0';
- When copying, the '\ 0' in the source string will be copied to the target string together;
- The target string (target space) must be large enough to store the source string;
- Another point is that the target string must be changeable
See the following code:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; const char* p = "XXXXXXXXXX"; printf("%s\n", strcpy(p, arr1)); return 0; }
The execution of the program is wrong, because the target string at this time is modified by const and cannot be modified.
Implementation of strcpy by user-defined function simulation
char* my_strcpy(char* dest, const char* src) { char* ret = dest; assert(dest && src); while (*dest++ = *src++)//Very good { ; } return ret; }
3,strcat()
Function prototype:
Function function:
Append the source string to the destination string and return the address of the first character of the destination string
Interpret the following codes:
#include<stdio.h> #include<string.h> int main() { char arr1[30] = "hello"; char arr2[] = "world"; strcat(arr1, arr2); printf("%s\n", arr1); return 0; }
The above code splices "world" after "hello", so the print results are as follows:
In fact, the precautions for using strcat library function are very similar to strcpy. I won't explain it again here:
- The source string must end with '\ 0';
- The target space must be large enough to accommodate the contents of the source string;
- The target space must be variable.
So imagine: if we let ourselves implement the strcat function, what should we do? First think about the general idea. First, we need to find the end flag '\ 0' of the target string, then splice the source string behind the target string, and finally return the address of the first character of the target string. It seems very simple. Let's implement it:
Implementation of strcat by user-defined function simulation
Code execution:
char* my_strcat(char* dest, const char* src) { char* ret = dest; assert(dest && src); //1. Found target string \ 0 while (*dest)//Note that it is wrong to write the loop condition as * dest + +, because \ 0 will be skipped. Please review it carefully { dest++; } //2. Copy source string while (*dest++ = *src++) { ; } return ret; }
4,strcmp()
Function prototype:
Function function:
Compare the dictionary order of the characters in the corresponding position
Standard provisions:
- If the first string > the second string, a number greater than 0 will be returned;
- If the first string = = the second string, 0 is returned;
- If the first string < the second string, a number less than 0 is returned.
Knock on the blackboard:
The two strings cannot be compared directly, nor can they be added or subtracted directly, because the string represents the address of the first character. In other words, if you compare directly, the comparison is not the content of the string, but the address, so it is wrong.
Implementation of strcmp by user-defined function simulation
Code execution:
int my_strcmp(const char* str1, const char* str2) { assert(str1 && str2); while (*str1 == *str2)//Notice that it is to judge the equality in the loop body, and think about why { if (*str1 == '\0') return 0; str1++; str2++; } if (*str1 > *str2)//return *str1 - *str2; return 1; else return -1; }
5,strncpy()
Function prototype:
Look at the following code:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "xxxxxxxxxxxxxx"; char arr2[] = "hello world"; strncpy(arr1, arr2, 5); printf("%s\n", arr1); return 0; }
Such functions are relatively safer, more controllable and more flexible.
6,strncat()
Function prototype:
Look at a piece of code:
#include<stdio.h> #include<string.h> int main() { char arr1[20] = "hello\0xxxxx"; char arr2[] = "world"; strncat(arr1, arr2, 3); printf("%s\n", arr1); return 0; }
From the above, we can see that '\ 0' will be automatically filled after appending, and it will be appended to the end of the first '\ 0' in the target string.
7,strncmp()
Function prototype:
Look at the following code:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "acbdef"; char arr2[] = "abcdef"; int ret = strncmp(arr1, arr2, 3); printf("%d\n", ret); return 0; }
Note: the above code compares the first three characters of the string, not the third character.
8,strstr()
Function prototype:
Return value:
Function function:
Find string
Take a look at the following code:
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; char arr2[] = "bcd"; char* ret = strstr(arr1, arr2); if (NULL == ret) printf("Can't find\n"); else printf("%s\n", ret); return 0; }
Implementation of STR by user-defined function simulation
Code execution:
char* my_strstr(const char* str, const char* substr) { const char* s1 = str; const char* s2 = substr; const char* cur = str; assert(str && substr); //exceptional case if (*substr == '\0') return (char*)str; while (*cur) { s1 = cur; s2 = substr; while (*s1 && *s2 && *s1 == *s2)//Attention * S1! =\ 0&&*s2!='\ 0 { s1++; s2++; } if (*s2 == '\0') return (char*)cur; cur++; } return NULL; }
9,strtok()
Function prototype:
Precautions before use:
- The sep parameter is a string that defines the set of characters used as separators;
- The first parameter specifies a string, which contains 0 or more tags separated by one or more separators in the sep string;
- The strtok function finds the next tag in str, ends it with '\ 0', and returns a pointer to this tag. (Note: strtok function will change the operated string, so the string segmented by strtok function is generally the content of temporary copy and can be modified);
- When the first parameter of strtok function is not NULL, the function will find the first tag in str, and strtok function will save its position in the string;
- When the first parameter of strtok function is NULL, the function will start at the saved position in the same string to find the next tag;
- A NULL pointer is returned if there are no more tags in the string
It can also be said that:
- When the strtok function finds the first tag, the first parameter of the function is not NULL;
- When the strtok function finds a non first tag, the first parameter of the function is NULL
Look at the following code:
#include<stdio.h> #include<string.h> int main() { const char* p = "@."; char arr[] = "zpengwei@yeah.net"; char buf[50] = { 0 };//As a temporary copy strcpy(buf, arr); char* str = strtok(buf, p); printf("%s\n", str);//zpengwei str = strtok(NULL, p); printf("%s\n", str);//yeah str = strtok(NULL, p); printf("%s\n", str);//net return 0; }
However, it seems too cumbersome to use in this way. Take a look at the following improved code:
#include<stdio.h> #include<string.h> int main() { const char* p = "@."; char arr[] = "zpengwei@yeah.net"; char buf[50] = { 0 };//As a temporary copy strcpy(buf, arr); char* str = NULL; for (str = strtok(buf, p); str != NULL; str = strtok(NULL, p)) { printf("%s\n", str); } //char* str = strtok(buf, p); //printf("%s\n", str);//zpengwei //str = strtok(NULL, p); //printf("%s\n", str);//yeah //str = strtok(NULL, p); //printf("%s\n", str);//net return 0; }
10,strerror()
Function prototype:
Return value:
Function function:
Returns the error information corresponding to the error code
Look at the following code:
//C language can operate files //Open file - fopen //When the library function is used, if an error occurs, the global error variable errno will be set as the error code generated by this execution of the library function //Errno is a global variable provided by C language, which can be used directly and placed in errno H in the document #include<stdio.h> #include<errno.h> #include<string.h> int main() { //Open file FILE* pf = fopen("test.txt", "r"); if (NULL == pf) { //What is the reason for the error printf("%s\n", strerror(errno)); return 0; } //read file //... //Close file fclose(pf); pf = NULL; return 0; }
Common string library functions are finally explained. Change your mood.
2, Character classification function
When using character manipulation functions, it should be noted that the header file is ctype h
The function is not introduced in detail.
Character conversion:
- int tolower(int c)
- int toupper(int c)
Code example:
#include<stdio.h> #include<ctype.h> int main() { char ch = 0; ch = getchar(); if (islower(ch)) ch = toupper(ch); else ch = tolower(ch); printf("%c\n", ch); return 0; }
3, Common memory operation functions
1,memcpy()
Function prototype:
Note that the third parameter in the memory operation function is in bytes.
Think about why it's a void * type?
Because the designer doesn't know what type the library function will be used to copy when designing the library function, it is best to design it as void *.
Look at the following code:
#include<stdio.h> #include<string.h> int main() { int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[5] = { 0 }; memcpy(arr2, arr1 + 5, 5 * sizeof(arr1[0])); int i = 0; for (i = 0; i < 5; i++) { printf("%d ", arr2[i]); } return 0; }
Implementation of memcpy by user-defined function simulation
Code execution:
void* my_memcpy(void* dest, const void* src, size_t num) { void* ret = dest;//Note that the return type is void *, not void, assert(dest && src); while (num--)//Use first, then-- { *(char*)dest = *(char*)src;//Think about why cast type to char *, because only it is most appropriate dest = (char*)dest + 1;//Note that direct dest++,src + + is wrong because it is an empty type src = (char*)src + 1; } return ret; }
2,memmove()
Function prototype:
In fact, C language only requires:
Memcpy can copy non overlapping memory space. Memmove handles those overlapping memory copies. That is, if the function of memcpy is A, the function of memmove is A+B
So what is overlapping memory copies? Please see the following code:
#include<stdio.h> #include<string.h> int main() { int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; memmove(arr1 + 2, arr1, 5 * sizeof(arr1[0]));//Overlapping memory copies occur when processing the same space int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr1[i]); } return 0; }
Implementation of memmove by user-defined function simulation
Code execution:
void* my_memmove(void* dest, const void* src, size_t num) { void* ret = dest; assert(dest && src); if (dest < src)//Copy back { while (num--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } } else//Copy back to front { //src = (char*)src + num - 1;// Be sure to - 1 //dest = (char*)dest + num - 1; //while (num--) //{ // *(char*)dest = *(char*)src; // dest = (char*)dest - 1; // src = (char*)src - 1; //} while (num--)//First use, then --, in the loop body is the num after -- (really wonderful) { *((char*)dest + num) = *((char*)src + num); } } return ret; }
3,memcmp()
Function prototype:
Return value:
It's relatively simple. Take a look at the following code:
#include<stdio.h> #include<string.h> int main() { int arr1[] = { 1,2,7,4,5 }; int arr2[] = { 1,2,3,4,5 }; int ret = memcmp(arr1, arr2, 9); printf("%d\n", ret); return 0; }
4,memset()
Function prototype:
Function parameters:
Function function:
Set memory in bytes
Look at the following code:
#include<stdio.h> #include<string.h> int main() { char arr[20] = { 0 }; memset(arr, 'x', 10); printf("%s\n", arr); return 0; }
You can also operate on integers, but because it is an operation on memory, you should consider the byte order of the size end. If you forget what the size end is, you can see this article:
4, Meet Enron meet you, not negative code, not negative Qing.
Ten thousand character blog posts are not easy to be original.