[those who invade the memory territory will be broken by attack] detailed explanation of C language string function

preface

There are many library functions in C language, including our common IO functions (printf, scanf), time functions (time), mathematical functions (fabs), string functions and so on.
The processing of characters and strings in C language is very frequent, but 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 it
This article will introduce you to string functions to help you better understand and learn string functions.

Find string length

strlen

introduce

Strlen parameter: size_t strlen( const char *string );
The strlen function is located under the < string. H > header file. The return value is the length of the string.
PS: the length must be a positive number, size_t is implemented through macro definition, and its type is unsigned int unsigned integer. This description will not be covered later in this article

effect

Calculate string length

strlen calculates the received address forward in 1 byte. When the terminator '\ 0' is encountered, the calculation stops.

matters needing attention

If the input string has no exact size, such as uninitialized, the returned value will be a random value, because the function will stop only when '\ 0' is encountered. As shown in the figure:

Moreover, since the return value of strlen is an unsigned integer, the subtraction result must be a positive integer, so you can't subtract at will or multiply negative numbers. As shown in the figure:

Of course, you can get the desired result by casting

Simulation Implementation

Knowing the principle, it is easy to implement strlen
There are three implementation methods, namely

  1. count
  2. Pointer minus pointer (pointer minus pointer is the number of elements between two addresses)
  3. recursion
    The code is as follows
size_t my_strlen1(const char* str) {//Counting method, when a number other than \ 0 is encountered, it will be + 1
	char *s = (char*)str;
	size_t count = 0;
	while (*s++ != '\0')
		count++;
	return count;
}
size_t my_strlen2(const char* str) {//Address minus address is the number of elements between two addresses
	char *s = (char*)str;
	while (*s++ != '\0');
	return (size_t)(s - str)-1;//Here - 1 is because s is at \ 0
}
size_t my_strlen3(const char* str) {//Recursive Method 
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen3(str + 1);
}

The results are as follows:

String function with unlimited length

strcpy

introduce

Parameters of strcpy: char * strcpy (char * STR1, const char * STR2);
The strcpy function is located under the < string. H > header file. Its return value is a pointer of type char *.

effect

Copy the contents of string str2 into string str1.

matters needing attention

  1. strcpy will also put \ 0 in it

  2. strcpy doesn't care about the size of the space. If you put an 8-byte string into a 4-byte size, the code can still be executed and will be forced into it. The result will report an error because it "can't be put"; So the target space must be large enough

  3. (the string must end with \ 0) the string str2 should have a specific size, similar to strcpy. Otherwise, the random value will be put into str1 and an error will be reported: like strcpy, the copy will only stop when str2 encounters \ 0

Simulation Implementation

code:

char* my_strcpy(char* s1, const char*s2) {
	assert(s1&&s2);//Assert function, judge null pointer
	char* ret = s1;
	while (*s1++ = *s2++)
		;
	return ret;
}

result:

strcat

introduce

Strcat parameters: char * strcat (char * STR1, const char * STR2);
The strcat function is located under the < string. H > header file. Its return value is a pointer of type char *.

effect

Append the string str2 to str1 and return a pointer to str1.

matters needing attention

  1. str1 should reserve a certain space for the position of str2, otherwise it will cross the boundary.
  2. str2 needs to have a fixed size, otherwise the random value will be entered and there will be a risk of crossing the boundary.
    Program crash

    Solution: just put it in \ 0

Simulation Implementation

code:

char* my_strcat(char* str1, const char* str2) {
	assert(str1 && str2);//Assert
	char* ret = str1;//Reserved str1 address
	while (*str1)
		str1++;
	//Found the location of \ 0 for str1
	while (*str1++ = *str2++)
		;
	//Add
	return ret;
}

result:

strcmp

introduce

Parameters of strcmp: int strcmp (const char * STR1, const char * STR2);
The strcmp function is located under the < string. H > header file.

effect

Compare the size and content of the string (not the length) (refer to the dictionary order) (ASCII value). If str1 > str2, a number greater than 0 is returned. If str1=str2, 0 is returned. If str1=str2, a number less than 0 is returned.
Usually returns 1, 0, - 1.

Simulation Implementation

code:

int my_strcmp (const char* str1,const char* str2) {
	assert(str1 && str2);
	while (*str1 && *str2){//ergodic
		if (*str1 > *str2)//Greater than return 1
			return 1;
		else if (*str1 < *str2)//Less than return - 1
			return -1;
		*str1++;//Equal to continue
		*str2++;
	}
	return 0;//The traversal ends, equals, and returns 0
}

result:

String function with limited length

explain

Because the length of strcpy, strcat and ctrcmp is not limited and has been mentioned in the notes of the above three functions, these functions are not safe and some problems will occur, such as cross-border access.
Therefore, in order to better use functions, C language stipulates the use of some relatively safe functions with limited length. These functions will be introduced next.
Note that it is not absolutely safe

strncpy

introduce

Parameters of strncpy:
char *strncpy( char *str1, const char *str2, size_t count );
Like strcpy, it is located under the < string. H > header file.
Compared with strcpy, there is an additional count parameter. Its function is to specify count bytes to be copied, which is used to solve the error prone problem of strcpy copying directly without looking at the size

matters needing attention

  1. If the count is greater than the length of str2, that is, there is not enough content to be copied in, then '\ 0' will be added
    Of course, if str2 does not specify a size, in this case, \ 0 will not be entered, but a random value will be stored.

Simulation Implementation

code:

char * my_strncpy(char * str1, const char *str2, size_t n)
{
	assert(str1 && str2);

	char *ret = str1;
	for (size_t i = 0; i < n; i++) {
		if (n>strlen(str1)){
			*(str1 + i) = '\0';//Handle the excess
		}
		else{
			*(str1 + i) = *str2++;
		}
	}
	return ret;
}


result:

strncat

introduce

Parameters of strncat:
char *strncat( char *str1, const char *str2, size_t count );
Under the < string. H > header file.
Like strncpy versus strcpy, strncat has an additional count parameter, which is used to specify the additional count bytes.

matters needing attention

  1. strncat does not really add count bytes, but will help you put an extra '\ 0' to end the string.
  2. strncat can only append count+1 characters at most. If count is greater than the length of the string to be appended, nothing will happen

Simulation Implementation

code:

char* my_strncat(char* str1, const char* str2,size_t count) {
	assert(str1 && str2);//Assert
	char* ret = str1;//Reserved str1 address
	while (*str1)
		str1++;
	//Found the location of \ 0 for str1
	while(count--){
		if (*str2 == '\0'){//Handle the case where the count is too large
			*str1 = '\0';
			break;
		}
		else{
			*str1++ = *str2++;
		}
	}
	//Add
	return ret;
}

result:

strncmp

introduce

Parameters of strncmp:
char *strncat( const char *str1, const char *str2, size_t count );
Under the < string. H > header file.
A count parameter is added to compare count bytes.

Simulation Implementation

code:

int my_strncmp(const char* str1, const char* str2,size_t count) {
	assert(str1 && str2);
	while (count--){//ergodic
		if (*str1 > *str2)//Greater than return 1
			return 1;
		else if (*str1 < *str2)//Less than return - 1
			return -1;
		*str1++;//Equal to continue
		*str2++;
	}
	return 0;//The traversal ends, equals, and returns 0
}

result:

String lookup function

As the name suggests, the function used to find a string

strstr

introduce

Parameters: char * strstr (const char * STR1, const char * STR2);
Find out whether str2 exists in str1, and return the starting address of the position where str2 first appears in str1. Otherwise, return a null pointer.

Simulation Implementation

code:

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	char* start = (char*)str1;//Here you need to cast the type to char*
	char* find = (char*)str2;//String to find
	char* p = (char*)str1;//cp is used to save the first address
	while (*p)
	{
		start = p;//Assign p to start and use start to find it to prevent the starting point of str2 from being found
		while (*start != '\0' && *find != '\0' && *start == *find)
		{
			//Loop, looking for Strings
			start++;
			find++;
		}
		if (*find == '\0')//find encountered \ 0, which means it was found
		{
			return p;//Return to p at this time
		}
		find = (char*)str2;//Not found, but find may have changed, so re assign
		p++;//p + + can get the next position of the original starting position
	}
	return NULL;
}

result:

strtok

introduce

Strtok parameters: char * strtok (char * STR1, const char * STR2);
Search str1 for the same character as str2 and set it to \ 0

  1. The first parameter str1 specifies a string that contains 0 or more tags separated by one or more separators in the str2 string.
  2. The strtok function finds the next tag in str1, 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 and can be modified.)
  3. The first parameter of the strtok function is not NULL, the function will find the first tag in str1, and the strtok function will save its position in the string.
  4. 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.
  5. If there are no more tags in the string, a NULL pointer is returned.
  6. This is implemented with static variables.

Error message report

strerror

introduce

Parameter: char * strError (int errnum);
The strerror function searches the internal array for the error number errnum and returns a pointer to the error message string. The error string generated by strerror depends on the development platform and compiler.

Memory operation function

memcpy

introduce

Parameter: void * memcpy (void * STR1, const void * STR2, size_t count);

  1. The memcpy function copies count bytes of data back from the position of str2 to the memory position of str1.
  2. This function will not stop when it encounters' \ 0 '.
  3. If there is any overlap between str2 and str1, the copied result is undefined.
  4. The data that memcpy can copy will not be limited, and multiple types of data can be copied

Simulation Implementation

code:

void* my_memcpy(void* arr1, const void* arr2, size_t count) {
	assert(arr1 && arr2);
	void* ret = arr1;
	while(count--) {
		*(char*)arr1 = *(char*)arr2;
		arr1 = (char*)arr1 + 1;
		arr2 = (char*)arr2 + 1;
	}
	return ret;
}

result:

memmove

introduce

Parameter: void * memmove (void * STR1, const void * STR2, size_t count);
Its function is similar to that of memcpy, which is to copy.
However, memmove is stronger than memcpy, because in some cases, memcpy cannot complete the overwrite copy. As shown in the figure.
In vs, memcpy can complete the overlay copy, but it cannot be completed in some compilers, so try to use memmove in this case.

Simulation Implementation

Special treatment shall be carried out for data repetition interval
code:

void* my_memmove(void* dest, const void* src, size_t count) {
	void *ret = dest;
	if (dest < src){//Copy from front to back

		while (count--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else{//Copy back to front
		while (count--) {
			*((char*)dest + count) = *((char*)src+count);
		}
	}
	return ret;
}

result:

memset

introduce

Parameters: void * memset (void * DeST, int c, size_t count);
This function can set all count bytes from dest to c

Simulation Implementation

code:

void* my_memset(void *arr, const int c, size_t count){
	void*ret = arr;
	for (size_t i = 0; i < count; i++){
		*((char*)arr + i) = c;
	}
	return ret;
}

result:

memcmp

introduce

Parameter: int memcmp(const void *str1, const void *str2, size_t n);
The C library function memcmp compares the first n bytes of storage area str1 and storage area str2.

Simulation Implementation

code:

void* my_memcpy(void* dest, const void* src, size_t n)
{
	assert(dest);
	assert(src);
	char* pdest = (char*)dest;
	const char* psrc = (const char*)src;
	while (n--)
	{
		*pdest++ = *psrc++;
	}
	return dest;`

🐂🐸 Sprinkle flowers at the end
Colored eggs are no colored eggs

Tags: C

Posted on Sun, 19 Sep 2021 22:26:48 -0400 by malam