String function and memory function

String and memory functions

C language itself has no string type, but its operation on string is more frequent. This chapter describes the usage and implementation of these functions.

String function

String length function strlen

Function declaration

size_t strlen(const char* str)
Return Value
This function returns the number of characters in string, excluding the terminal NULL. No return value is reserved to indicate an error.

Parameter
string - Null-terminated string

Function usage

  • '\ 0' is the end of string flag, so strlen function calculates the number of characters before \ 0.

  • The parameter is the address of the first character of the string, and the string must be a string ending in \ 0.

//1.
char arr1[] = "abcd";
printf("%d\n", strlen(arr1));//4
//2.
char arr2[] = { 'a','b','c','d' };
printf("%d\n", strlen(arr2));//Random value
//3.
int a = 10;
printf("%d\n", strlen(a));//report errors

1. The passed parameter is a string address ending in \ 0, which meets the requirements of strlen.
2. Although the passed parameter is a string address, it does not end with \ 0, so strlen will keep looking until \ 0 is found.
The passed parameter is not an address at all. This integer will be treated as an address by strlen, so the illegal memory at 0x0A address is accessed. As shown in the figure:

  • The return type of strlen function is size_t. Note the use of unsigned numbers.
size_t ret = strlen("abcdef");
printf("%u\n", ret);

Unsigned numbers are received and printed in unsigned form. Do not use unsigned number operation result ratio size:

 if (strlen("abc") - strlen("abcdef") < 0) {
    printf("hehe\n");
}
else {
    printf("haha\n");
}

The operation result of an unsigned number is shaped and promoted to an unsigned number, so the subtraction of the two is regarded as an unsigned number and will not be less than zero.

Simulation Implementation

//1. Calculator
#include <stdio.h>
#include <assert.h>

size_t my_strlen(const char* p)
{
	assert(p);
	size_t ret = 0;
	while (*p++ != '\0')
	{
		ret++;
	}
	return ret;
}

int main()
{
	char arr[] = "abcdef";
	size_t ret = my_strlen(arr);
	printf("%u\n", ret);
	return 0;
}
//2. Use pointer - pointer
size_t my_strlen(char* p)
{
	char* s = p;
	while (*p)
	{
		p++;
	}
	return p - s;
}

int main()
{
	char arr[] = "abcdef";
	size_t ret = my_strlen(arr);
	printf("%u\n", ret);
	return 0;
}

String copy function strcpy

Function declaration

char* strcpy ( char* strDestination, const char* strSource );
Return Value
This function returns the destination string. No return value is reserved to indicate an error.

Parameters
1. strDestination - Destination string
2. strSource - Null-terminated source string

Remarks
1The strcpy function copies the string pointed by strSource to the array pointed by strDestination,including the terminating null character. 
No overflow checking(Overflow check) is performed when strings are copied. The behavior of strcpy is undefined(undefined) if the source and destination strings overlap(overlap).

strcpy copies the contents of the source string (including \ 0) to the target space in turn.

Function usage

  • The source string ends with '\ 0', and strcpy will copy \ 0 in the source string to the target space.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-my0d4jle-1632139207004) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20210920174627738. PNG)]

\ 0 will be copied with the copy. If there is \ 0 in the source string, the subsequent elements will not be copied, because \ 0 will be used as the end flag when reading.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-lsdz9yn0-1632139207007) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20210920174720243. PNG)]

If the source string does not end with \ 0, strcpy will access illegal memory all the way back.

  • The target space is modifiable and large enough to store the source string.
//1.
char arr1[] = "xxx";//The target space is not large enough
char arr2[] = "abcdef";
//.2
const char arr1[] = "xxxxxxxxxx";//The target space cannot be modified
char arr2[] = "abcdef";

strcpy(arr1, arr2);

The above two situations also need to be avoided.
When strcpy is used in vs2019 environment, it will give an unsafe warning. This function will not check whether the array is out of bounds before copying, and the warning is normal. But as qualified programmers, we have an obligation to eliminate risks.

Simulation Implementation

#include <stdio.h>
#include <assert.h>

char* my_strcpy(char* p1, const char* p2)
{
	assert(arr1 && arr2);
	char* tmp = p1;
	while (*p1++ = *p2++)
	{
		;
	}
	return tmp;
}

int main()
{
	char arr1[] = "xxxxxxxxxxxxxxxx";
	char arr2[] = "abcdef";
	char* ret = my_strcpy(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

String append function strcat

Function declaration

char* strcat ( char* strDestination, const char* strSource );
Return Value
This function returns the destination string. No return value is reserved to indicate an error.

Parameters
1. strDestination - Null-terminated destination string
2. strSource - Null-terminated source string

Remarks
The strcat function appends strSource to strDestination and terminates the resulting string with a null character.
The initial character of strSource overwrites the terminating null character of strDestination. 
No overflow checking is performed when strings are copied or appended. The behavior of strcat is undefined if the source and destination strings overlap.

strcat appends the source string including \ 0 to the end of the destination string and overwrites \ 0 in the destination space.

Function usage

  • The source string must end with '\ 0'. strcat will append \ 0 to the end of the target space as the string end flag.

    [the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-ra7dadoq-1632139207009) (C: \ users \ administrator \ appdata \ roaming \ typora \ typora user images \ image-20210920175328212. PNG)]

This example also shows that the source string does not end with \ 0, thus accessing illegal space.

  • The target space must be large enough and modifiable to append strings.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-b3y55f2z-1632139207014) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20210920175441173. PNG)]

The size of the target string is determined by the initialization content. Obviously, this initialization method cannot append strings. Similarly, the target string cannot be decorated with const. strcat still does not perform overflow check when calling, and only reports an error after overflow.

Simulation Implementation

#include <stdio.h>
#include <assert.h>

char* my_strcat(char* p1, char* p2)
{
	char* tmp = p1;
	while (*p1)
	{
		p1++;
	}
	while (*p1++ = *p2++)
	{
		;
	}
	return tmp;
}

int main()
{
	char arr1[20] = "xxxx";
	char arr2[] = "abcdef";
	char* ret = my_strcat(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

String comparison function strcmp

Function declaration

int strcmp ( const char* string1, const char* string2 );
Return Value
The return value for this function indicates the relation of string1 to string2.
+-------+------------------------------------+
| Value | Relationship of string1 to string2 |
+-------+------------------------------------+
|  <0   |    string1 less than string2       |
|   0   |    string1 identical to string2    |
|  >0   |    string1 greater than string2    |
+-------+------------------------------------+

Parameters
1. string1, string2
2. Null-terminated strings to compare

Remarks
The strcmp function compares string1 and string2, what starts comparing the first character of each string, if are equal, continuing with the follows until the differ or a null-character is reached, and returns a value indicating their relationship.  

strcmp traversal compares whether the ASCII code values of the characters at the corresponding positions of two strings are equal.

Function usage

  • Return value of function
    1. When string 1 is less than string 2, a number less than 0 is returned
    2. When string 1 is equal to string 2, 0 is returned
    3. When string 1 is greater than string 2, a number greater than 0 is returned
  • Both must end with \ 0 as the end of the string, otherwise cross-border access will still occur.

Simulation Implementation

#include <stdio.h>
#include <assert.h>

int my_strcmp(char* p1, char* p2)
{
	assert(p1 && p2);
	while (*p1 == *p2)
	{
		if (*p1 == '\0')
			return 0;
		p1++;
		p2++;
	}
	return *p1 - *p2;
}

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abc";
	int ret = my_strcmp(arr1, arr2);
	if (ret > 0)
	{
		printf(">\n");
	}
	else if (ret < 0)
	{
		printf("<\n");
	}
	else
	{
		printf("=\n");
	}
	return 0;
}

String copy function strncpy - Length Limited

Function declaration

char* strncpy ( char* strDest, const char* strSource, size_t count );
Return Value
This function returns strDest. No return value is reserved to indicate an error.

Parameters
1. strDest - Destination string
2. strSource - Source string
3. count - Number of characters to be copied

Remarks
The strncpy function copies the initial count characters of strSource to strDest and returns strDest.
If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. 
If count is greater than the length of strSource, the destination string is padded(fill) with null characters up to length count. 
The behavior of strncpy is undefined if the source and destination strings overlap.

The strcpy function copies count characters from the source string to the target string. If the count is greater than the length of the source string, it will be filled with \ 0.

Function usage

  • The target string is modifiable and large enough
  • If count is less than the number of source strings, \ 0 will not be appended. If count is greater than the number of source strings, \ 0 will be filled into count characters.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-xlpmumuo-1632139207016) (C: \ users \ administrator \ appdata \ roaming \ typora \ typora user images \ image-20210920181214589. PNG)]

Simulation Implementation

#include <stdio.h>
#include <assert.h>

char* my_strncpy(char* p1, char* p2, int n)
{
	char* tmp = p1;
	assert(p1 && p2);
	while (n-- && *p1++ = *p2++)
	{
		;
	}
	while (n)
	{
		*p1++ = '\0';
		n--;
	}
	return tmp;
}

int main()
{
	char arr1[] = "xxxxxxxxxxx";
	char arr2[] = "abc";
	int input = 0;
	scanf("%d", &input);
	char* ret = my_strncpy(arr1, arr2, input);
	printf("%s\n", ret);
	return 0;
}

String append function strncat - Length Limited

Function declaration

char* strncat ( char* strDest, const char* strSource, size_t count );
Return Value
This function returns a pointer to the destination string. No return value is reserved to indicate an error.

Parameters
1. strDest - Null-terminated destination string
2. strSource - Null-terminated source string
3. count - Number of characters to append

Remarks
The strncat function appends, at most, the first count characters of strSource to strDest. The initial character of strSource overwrites the terminating null character of strDest. 
If a null character appears in strSource before count characters are appended, strncat appends all characters from strSource, up to the null character. 
If count is greater than the length of strSource, the length of strSource is used in place of count. The resulting string is terminated with a null character. 
If copying takes place between strings that overlap, the behavior is undefined.

Append count characters of the source string at the end of the target string, and add \ 0 at the end by default.

Function usage

  • Append to the end of the target string. The default complement is' \ 0 '. count exceeds the number of source strings and is not appended.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-tnvpp1yd-1632139207017) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20210920181952737. PNG)]

Simulation Implementation

#include <stdio.h>
#include <assert.h>

char* my_strncat(char* p1, char* p2, int n)
{
	assert(p1 && p2);
	char* tmp = p1;
	while (*p1)
	{
		p1++;
	}
	while (n-- && *p1++ = *p2++)
	{
		;
	}
	if (n == 0)
	{
		*p1 = '\0';
	}
	return tmp;
}

int main()
{
	char arr1[20] = "xxxx";
	char arr2[] = "abcd";
	int intput = 0;
	scanf("%d", &input)
	char* ret = my_strncat(arr1, arr2, input);
	printf("%s\n", ret);
	return 0;
}

String comparison function strncmp - Length Limited

Function declaration

int strncmp ( const char* string1, const char* string2, size_t count );
Return Value
The return value for each of these functions indicates the relation of string1 to string2.
+-------+------------------------------------+
| Value | Relationship of string1 to string2 |
+-------+------------------------------------+
|  <0   |    string1 less than string2       |
|   0   |    string1 identical to string2    |
|  >0   |    string1 greater than string2    |
+-------+------------------------------------+

Parameters
1. string1, string2 - Null-terminated strings to compare.
2. count - Number of characters to compare

Remarks
The strncmp function lexicographically compares, at most, the first count characters in string1 and string2 and returns a value indicating the relationship between the substrings.

Compares the first count characters of two strings and returns the relevant value.

#include <stdio.h>
#include <assert.h>

int my_strncmp(char* p1, char* p2, int n)
{
	assert(p1 && p2);
	while (*p1++ == *p2++ && --n)
	{
		if (*p1 == '\0')
			return 0;
	}
	return *p1 - *p2;
}

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abc";
	int input = 0;
	scanf("%d", &input);
	int ret = my_strncmp(arr1, arr2, input);
	printf("%d\n", ret);
	return 0;
}

String lookup function str

Function declaration

char* strstr ( const char* string, const char* strCharSet );
Return Value
This function returns a pointer to the first occurrence of strCharSet in string, or NULL if strCharSet does not appear in string. 
If strCharSet points to a string of zero length, the function returns string.

Parameters
1. string - Null-terminated string to search
2. strCharSet - Null-terminated string to search for

Remarks
The strstr function returns a pointer to the first occurrence of strCharSet in string. The search does not include terminating null characters. 

Find the position where the substring first appears in the target string. If yes, return the starting position. If no, return a null pointer.

Simulation Implementation

#include <stdio.h>
#include <assert.h>

char* my_strstr(const char* p1, const char* p2)
{
	assert(p1 && p2);
	char* s1;
	char* s2;
	char* cp = p1;
	while (*cp)
	{
		s1 = cp;
		s2 = p2;
		while (*s2 && *s1 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cp;
		cp++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "i am a good student,hehe student";
	char arr2[] = "student";
	char* ret = my_strstr(arr1, arr2);
    if (ret == NULL)
    {
        printf("can't find\n");
    }
    else
    {
        printf("%s\n", ret);
    }
	return 0;
}

Memory function

Memory copy function memcpy

Function declaration

void* memcpy ( void* dest, const void* src, size_t count );
Return Value
memcpy returns the value of dest.

Parameters
1. dest - New buffer
2. src - Buffer to copy from
3. count - Number of characters to copy(bytes)

Remarks
The memcpy function copies count bytes of src to dest. 
If the source and destination overlap(overlap), this function does not ensure that the original source bytes in the overlapping region(region) are copied before being overwritten. Use memmove to handle overlapping regions.

memcpy copies the contents of the first count bytes of the source memory to the target memory.

Function usage

  • If the source space and the target space overlap, the content of the source string will be overwritten when copying.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-nkab06qn-1632139207019) (C: \ users \ administrator \ appdata \ roaming \ typora \ user images \ image-20210920192543934. PNG)]

The C standard does not require memcpy to copy the contents with memory overlap, but the compiler may also optimize it. memmove can be used to copy the contents of memory overlap.

Simulation Implementation

#include <stdio.h>
#include <assert.h>

void* my_memcpy(void* p1, const void* p2, size_t num)
{
	assert(p1 && p2);
    void* ret = p1;
    while (num--)
    {
        *(char*)p1= *(char*)p2;
        (char*)p2 = (char*)p2 + 1;
        (char*)p1 = (char*)p1 + 1;
    }
    return ret;
}

int main()
{
    int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int arr2[20] = { 0 };
    my_memcpy(arr2, arr1, 10 * sizeof(arr1[0]));
    int i = 0;
    for (i = 0; i < 20; i++)
    {
        printf("%d ", arr2[i]);
    }
    return 0;
}

Memory move function memmove

Function declaration

void* memmove ( void* dest, const void* src, size_t count );
Return Value
memmove returns the value of dest.

Parameters
1. dest - Destination object
2. src - Source object
3. count - Number of bytes of characters to copy

Remarks
The memmove function copies count bytes of characters from src to dest. 
If some regions of the source area and the destination overlap, memmove ensures that the original source bytes in the overlapping region are copied before being overwritten.

memmove copies the contents of the first count bytes of the source space to the target space, and supports the copying of memory overlaps.

Simulation Implementation

#include <stdio.h>
#include <assert.h>

void* my_memmove(void* dest, void* src, size_t count)
{
	void* tmp = dest;
	assert(dest && src);
	if (dest < src)
	{
		while (count--)
		{
			//From front to back
			*(char*)dest = *(char*)src;
			(char*)dest = (char*)dest + 1;
			(char*)src = (char*)src + 1;
        }
	}
	else
	{
		while (count--)
		{
			//From back to front
			*((char*)dest+count) = *((char*)src + count);
		}
	}
	return tmp;
}

int main()
{
	int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	//my_memmove(arr, arr+2, 4*sizeof(arr[0]));
	my_memmove(arr+2, arr, 4*sizeof(arr[0]));
	int i = 0;
	for (i=0; i<10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-je1gnhug-1632139207020) (C: \ users \ administrator \ appdata \ roaming \ typora \ typora user images \ image-20210917154241067. PNG)]

Memory comparison function memcmp

Function declaration

int memcmp ( const void* buf1, const void* buf2, size_t count );
Return Value
The return value indicates the relationship between the buffers.
+-------+------------------------------------+
| Value | Relationship of string1 to string2 |
+-------+------------------------------------+
|  <0   |    string1 less than string2       |
|   0   |    string1 identical to string2    |
|  >0   |    string1 greater than string2    |
+-------+------------------------------------+

Parameters
1. buf1 - First buffer
2. buf2 - Second buffer
3. count - Number of characters

Remarks
The memcmp function compares the first count bytes of buf1 and buf2 and returns a value indicating their relationship.

Compare the contents of the first count bytes of the two memory spaces and return the relevant values.

Simulation Implementation

int my_memcmp(const void* buf1, const void* buf2, size_t count) {
	assert(buf1 && buf2);
	while (count-- && (*(char*)buf1 == *(char*)buf2)) {
		(char*)buf1 += 1;
		(char*)buf2 += 1;
	}
	return *(char*)buf1 - *(char*)buf2;
}
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,6 };
	int ret = my_memcmp(arr1, arr2, 1 * sizeof(int));
	printf("%d\n", ret);
	return 0;
}

Memory initialization function memset

Function declaration

void* memset ( void* dest, int c, size_t count );
Return Value
memset returns the value of dest.

Parameters
1. dest - Pointer to destination
2. c - Character to set
3. count - Number of characters

Remarks
The memset function sets the first count bytes of dest to the character c.

Initialize the first count bytes of the target space to the shaping data c.

Function usage

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-4defa5rd-1632139207021) (C: \ users \ administrator \ appdata \ roaming \ typora \ typora user images \ image-20210920194823468. PNG)]

) {
assert(buf1 && buf2);
while (count-- && ((char)buf1 == (char)buf2)) {
(char*)buf1 += 1;
(char*)buf2 += 1;
}
return (char)buf1 - (char)buf2;
}
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2,3,4,6 };
int ret = my_memcmp(arr1, arr2, 1 * sizeof(int));
printf("%d\n", ret);
return 0;
}

### Memory initialization functions ` memset`

#### Function declaration

````c
void* memset ( void* dest, int c, size_t count );
Return Value
memset returns the value of dest.

Parameters
1. dest - Pointer to destination
2. c - Character to set
3. count - Number of characters

Remarks
The memset function sets the first count bytes of dest to the character c.

Initialize the first count bytes of the target space to the shaping data c.

Function usage

[external chain picture transferring... (img-4DeFA5Rd-1632139207021)]

Keywords: C

Added by soulroll on Tue, 21 Sep 2021 11:18:06 +0300