This chapter focuses on the use and precautions of library functions dealing with characters and strings
The processing of characters and strings in C language is very frequent,
However, C language itself has no string type. Strings are usually placed in constant strings or character arrays.
String constants apply to string functions that do not modify them
catalogue
I strlen function: get string length
II String function with unlimited length
strcpy function: copy of string
strcat function: string concatenation
strcmp function: string comparison
III Introduction to string functions with limited length
1. Character classification function
2. Character conversion function
I strlen function: get string length
size_t strlen ( const char * str );
The string ends with '\ 0', and the strlen function returns the number of characters that appear before '\ 0' in the string
Note:
- The string pointed to by the parameter must end with '\ 0'.
- Note that the return value of the function is size_t. Is unsigned (error prone)
Examples
#include <stdio.h> int main() { const char*str1 = "abcdef"; const char*str2 = "bbb"; if(strlen(str2)-strlen(str1)>0) { printf("str2>str1\n"); } else { printf("srt1<str2\n"); } return 0; }
Since the return value of the strlen function is size_t is an unsigned integer
When two unsigned integers are subtracted, the result is also an unsigned integer
So the result printed here is STR2 > STR1
Three ways to simulate the implementation of strlen function
Mode 1:
//Counter mode int my_strlen(const char * str) { int count = 0; while(*str) { count++; str++; } return count; }
Mode 2:
//Do not create temporary variable counters, use recursion int my_strlen(const char * str) { if(*str == '\0') return 0; else return 1+my_strlen(str+1); }
Mode 3:
//Pointer - pointer mode int my_strlen(char *s) { char *p = s; while(*p != '\0' ) p++; return p-s; }
II String function with unlimited length
strcpy function: copy of string
char* strcpy(char * destination, const char * source );
Copies the C string pointed by source into the array pointed by destination, including theterminating null character (and stopping at that point).
- The source string must end with '\ 0'.
- The '\ 0' in the source string will be copied to the destination space.
- The destination space must be large enough to hold the source string.
- Target space must be variable
Simulation Implementation
#include<stdio.h> #include<assert.h> char* my_strcpy(char* dest, const char* src) { assert(dest && src);//Assert char* ret = dest; while (*dest++ = *src++) { ; } return ret; } int main() { char arr1[20] = "xxxxxxxxxxxxx"; char arr2[] = "hello"; my_strcpy(arr1, arr2); printf("%s", arr1); printf("%s\n",my_strcpy(arr1, arr2)); return 0; }
strcat function: string concatenation
char * strcat ( char * destination, const char * source );
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
- 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 modifiable.
Simulation Implementation
char* my_strcat(char* dest, const char* src) { assert(dest&&src); int i = 0; while (*(dest + i) != '\0') { i++; } while (*src != '\0') { *(dest + i++) = *src++; } *(dest + i) = '\0'; return dest; }
strcmp function: string comparison
int strcmp ( const char * str1, const char * str2 );
This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
Standard provisions:
- If the first string is greater than the second string, a number greater than 0 is returned
- If the first string is equal to the second string, 0 is returned
- If the first string is less than the second string, a number less than 0 is returned
int my_strcmp (const char * src, const char * dst) { int ret = 0 ; assert(src != NULL); assert(dest != NULL); while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) ++src, ++dst; if ( ret < 0 ) ret = -1 ; else if ( ret > 0 ) ret = 1 ; return( ret ); }
III Introduction to string functions with limited length
strncpy function
char * strncpy ( char * destination, const char * source, size_t num );
Copies the first num characters of source to destination. If the end of the source C string(which is signaled by a null-character) is found before num characters have been copied,destination is padded with zeros until a total of num characters have been written to it.
- Copy num characters from the source string to the destination space.
- If the length of the source string is less than num, after copying the source string, append 0 to the end of the target until num
#include<stdio.h> #include<string.h> int main() { char arr1[] = "xxxxxxxxxxxxxxxx"; char arr2[] = "hello world"; strncpy(arr1, arr2, 5); printf("%s\n", arr1); //helloxxxxxxxxxxx }
If the length of the source string is less than num, after copying the source string, append 0 to the end of the target until num
int main() { char arr1[] = "xxxxxxxxxxxxxxxx"; char arr2[] = "he"; strncpy(arr1, arr2, 5); printf("%s\n", arr1); //he\0\0\0 ->he }
Simulation Implementation
#include<stdio.h> #include<assert.h> char* my_strncpy(char* dest, const char* str, size_t n) { assert(dest && str); char* ret = dest; while (n--) { *dest++ = *str++; } return ret; } int main() { char arr1[] = "xxxxxxxxxx"; char arr2[] = "abcde"; printf("%s\n", my_strncpy(arr1, arr2, 4)); // abcdxxxxxx return 0; }
strncat function
- Function: a string function that connects the specified number of elements
- strncat connects the source specified string from the destination string counting from left to right to the first '\ 0'
char * strncat ( char * destination, const char * source, size_t num );
Appends the first num characters of source to destination, plus a terminating null-character.
If the length of the C string in source is less than num, only the content up to the terminating null-character is copied
#include<stdio.h> #include<string.h> int main() { char str1[20]; char str2[20]; strcpy(str1, "To be "); strcpy(str2, "or not to be"); strncat(str1, str2, 6); puts(str1); return 0; }
- be careful:
After strncat is appended, it will actively put a '\ 0' after the append to ensure that it is a string.
Simulation Implementation
#include<stdio.h> #include<assert.h> char* my_strncat(char* dest, const char* str, size_t n) { assert(dest && str); char* ret = dest; while (*dest) { dest++; } while (n--) { *dest++ = *str++; } *dest = '\0'; return ret; } int main() { char arr1[20] = "hello\0xxxxx"; char arr2[] = "worldxxxxx"; printf("%s\n", my_strncat(arr1, arr2, 5)); //helloworld return 0; }
strncmp function
int strncmp ( const char * str1, const char * str2, size_t num );
The comparison shows that two characters are different, or a string ends, or num characters are all compared
- Function: implement the character number comparison function at the specified position
#include <stdio.h> #include <string.h> int main() { char str[][5] = { "R2D2" , "C3PO" , "R2A6" }; int n; puts("Looking for R2 astromech droids..."); for (n = 0; n < 3; n++) if (strncmp(str[n], "R2xx", 2) == 0) { printf("found %s\n", str[n]); } return 0; }
Simulation Implementation
#include<stdio.h> #include<assert.h> int my_strncmp(char* dest, const char* str, size_t n) { int ret = 0; assert(dest && str); while (n && !(*dest - *str)) { n--; dest++; str++; } if (n && *dest - *str > 0) return 1; else if (n && *dest - *str < 0) return -1; return ret; } int main() { char arr1[] = "abcdef"; char arr2[] = "abcqqqqq"; printf("%d\n", my_strncmp(arr1, arr2, 3)); return 0; }
IV String lookup function
strstr function
Function: judge whether a string is a subset of another string. If yes, return the address from the first equal
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of
str1.
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abbbcdef"; char arr2[] = "bbc"; char* ret = strstr(arr1, arr2); if (NULL == ret) printf("Can't find\n"); else printf("%s\n", ret); // bbcdef return 0; }
Simulation Implementation
#include<stdio.h> #include<assert.h> char* my_strstr(const char* str, const char* substr) { const char* s1 = str; const char* s2 = substr; const char* cur = str; assert(str && substr); if (*substr == '\0') { return (char*)str; } while (*cur) { s1 = cur; s2 = substr; while (*s1 && *s2 && *s1 == *s2) { s1++; s2++; } if (*s2 == '\0') return (char*)cur; cur++; } return NULL; } int main() { char arr1[] = "abbbcdef"; char arr2[] = "bbc"; char* ret = my_strstr(arr1, arr2); if (NULL == ret) printf("Can't find\n"); else printf("%s\n", ret);//bbcdef return 0; }
strtok function
- Function: cut a string of strings according to the separator
Note:
char * strtok ( char * str, const char * sep );
- The sep parameter is a string that defines the set of characters used as delimiters.
- The first parameter specifies a string that 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: the strtok function will change the string to be manipulated, so the string segmented by the strtok function is generally a temporary copy of the content and can be modified.)
- The first parameter of the strtok function is not NULL. The function will find the first tag in str, and the strtok function will save its position in the string.
- The first parameter of strtok function is NULL. The function will start at the position saved in the same string to find the next tag.
- If there are no more tags in the string, a NULL pointer is returned
#include <string.h> int main() { const char* p = "@.#,"; char arr[] = "zhangsan@qq.com"; char buf[50] = { 0 };// "zhangsan@qq.com"; strcpy(buf, arr); char* str = strtok(buf, p); printf("%s\n", str);//zhangsan str = strtok(NULL, p); printf("%s\n", str);//qq str = strtok(NULL, p); printf("%s\n", str);//com str = strtok(NULL, p); printf("%s\n", str); //strtok - return NULL from start return 0; }
V Error message report
strerror function
- Function: translate the error code into error information
- In C language, some information is specified, error code - error information
#include<stdio.h> #include<string.h> int main() { int i = 0; for (i = 0; i < 10; i++) { printf("%d = %s\n", i, strerror(i)); } return 0; }
Examples of uses:
C language can operate files, open files - 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 and can be used directly. It is in errno H in the file
#include<stdio.h> #include <errno.h> #include<string.h> int main() { FILE* pf = fopen("test.txt", "r"); if (NULL == pf) { //What is the reason for the error printf("%s\n", strerror(errno)); //No such file or directory return 0; } //read file //... //Close file fclose(pf); pf = NULL; return 0; }
Vi Character operation
1. Character classification function
For example: isdigit
char ch = '0'; if (ch >= '0' && ch <= '9') { //complex } if (isdigit(ch)) { //Convenient and fast }
2. Character conversion function
int tolower ( int c ); //Change uppercase to lowercase int toupper ( int c ); //Convert lowercase to uppercase
#include<stdio.h> #include <ctype.h> int main() { char ch = 0; while (ch = getchar()) { if (islower(ch)) { ch = toupper(ch); } else { ch = tolower(ch); } printf("%c", ch); } return 0; }
VII Memory operation function
memcpy function
void * memcpy ( void * destination, const void * source, size_t num );
Function: it can copy different types of data
#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 * sizeof(arr1[0])); int i = 0; for (i = 0; i < 5; i++) { printf("%d ", arr2[i]); // 1 2 3 4 5 } return 0; }
be careful:
- The function memcpy copies num bytes of data back to the memory location of destination from the location of source.
- This function will not stop when it encounters' \ 0 '.
- If there is any overlap between source and destination, the copied result is undefined.
Simulation Implementation
#include<stdio.h> #include <assert.h> void* my_memcpy(void* dest, const void*src, size_t num) { void* ret = dest; assert(dest && src); while (num--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } return ret; } int main() { int arr3[] = { 1,2,3,4,5,6,7,8,9,10 }; int arr4[5] = { 0 }; my_memcpy(arr4, arr3+5, 5*sizeof(arr3[0])); int i = 0; for (i = 0; i < 5; i++) { printf("%d ", arr4[i]); //6 7 8 9 10 } return 0; }
- C language only requires:
- memcpy can copy non overlapping memory space
- memmove to handle those overlapping copies
memmove function
Function: it can copy different types of data, but it can overlap
#include<stdio.h> #include<string.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; memmove(arr + 2, arr, 20); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); //1 2 1 2 3 4 5 8 9 10 } return 0; }
Attention
- The difference from memcpy is that the source memory block and target memory block processed by the memmove function can overlap.
- If the source space and target space overlap, you have to use the memmove function.
Simulation Implementation
#include<stdio.h> #include <assert.h> void* my_memmove(void* dest, const void* src, size_t num) { void* ret = dest; assert(dest && src); if (dest < src) { //Front - > rear while (num--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } } else { //Rear - > front while (num--) { *((char*)dest+num) = *((char*)src + num); } } return ret; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; my_memmove(arr + 2, arr, 20); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); //1 2 1 2 3 4 5 8 9 10 } return 0; }
memset function
Function: set a piece of memory space to the value you want, and modify it in bytes
#include<stdio.h> #include<string.h> int main() { //char arr[20] = { 0 }; //memset(arr, 'x', 10); //printf("%s\n", arr); //xxxxxxxxxx int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; memset(arr, '\0', 10); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); // 0 0 0 4 5 6 7 8 9 10 } //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 ... Change the first 10 bytes to 0 //00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 return 0; }
memcmp function
Function: memory comparison
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
Compare num bytes starting from ptr1 and ptr2 pointers, regardless of whether there is' \ 0 ', you can compare a few bytes if you let it compare a few bytes
#include<stdio.h> #include<string.h> int main() { int arr1[] = { 1,2,7,4,5 }; int arr2[] = { 1,2,3,4,5 }; printf("%d\n", memcmp(arr1, arr2, 9)); //1 / / 9 means comparing the first 9 bytes return 0; }