# 2, strlen function (find string length)

## Introduction to strlen function

The strlen function is used to find the length of a string (excluding \ 0). For example, the length of the string "abc" is 3. How do we use the strlen function in the code?

```#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; }
```

The program results are shown in the figure below:

The results of our program may be surprised. The length of string str2 is 3 and the length of string str1 is 6. Why did str2 > str1 finally print?

After consulting the data, it is found that the type of return value of strlen function is size_t (unsigned integer), so the operation result between unsigned integers is still unsigned integer. 3-6 is indeed equal to - 3, and the final print is the complement of - 3, and - 3 is obtained from the binary original code- The original code of 3 is 1000000000000000000000000000000011, and the complement of - 3 is 011111111111111111111111101, which is a positive number. Therefore, the result of strlen(str2)-strlen(str1) is greater than 0.

Features and precautions of strlen:

• The string has' \ 0 'as the end flag. The strlen function returns the number of characters that appear before' \ 0 'in the string (excluding' \ 0 ').
• The string pointed to by the parameter must end with '\ 0'.
• Note that the return value of the function is size_t, which is unsigned. (error prone)
• The header file required to call the strcpy function is string.h

## Simulation Implementation of strlen function

Method 1: counter method

```#include <stdio.h>
#include <string.h>
int my_strlen(const char* str)
{
int count = 0;
while (*str++!='\0')
{
count++;
}
return count;
}
int main()
{
char* str1 = "abcdef";
int ret = my_strlen(str1);
printf("%d", ret);
return 0;
}
```

Code running results: (the following running results are consistent with the following figure)

Method 2: recursive method

```#include <stdio.h>
#include <string.h>
int my_strlen(const char* str)
{
if(*str == '\0')
return 0;
else
return 1+my_strlen(str+1);
}
int main()
{
char* str = "abcdef";
int ret = my_strlen(str);
printf("%d", ret);
return 0;
}
```

Method 3: pointer minus pointer

```int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}
int main()
{
char* str = "abcdef";
int ret = my_strlen(str);
printf("%d", ret);
return 0;
}
```

# 3, strcpy function (string copy)

## Introduction to strcpy function

Let's first look at the return value type and value passing of strcpy function.

Looking up the data, we can see that the first parameter passed in by strcpy function is the target address, the second parameter is the source address, and the return value type is char *.

For example, the following code:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abcdef";
char str2[] = "zjr";
strcpy(str1, str2);
printf("%s", str1);
return 0;
}
```

The code execution results are shown in the figure below:

Features and precautions of strpy function:

• 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.
• The target space must be variable.

## Simulation Implementation of strcpy function

```char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;
}
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abcdef";
char str2[] = "zjr";
my_strcpy(str1, str2);
printf("%s", str1);
return 0;
}
```

The reason why const is used in the source string address in the formal parameter of my_strcpy function is to ensure that the content of the destination string is modified instead of the content of the source string. The assert function is used internally in my_strcpy function to ensure that neither the incoming destination string address nor the source string address is a null pointer. If it is a null pointer, an error will be reported during program code execution.

The running result of the above code is:

Briefly introduce the assert function:

The null pointer passed in will report an error, otherwise the program execution will not be affected.

# 4, strcat function (string append)

## Introduction to strcat function

The return value type of strcat function is char *, which can return the starting address of the appended string. The first parameter is the address of the destination string and the second parameter is the address of the source string.

Header file required to use strcat function:

Use of strcat function:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abcd";
char str2[] = "efgh";
char* ret = strcat(str1, str2);
printf("%s", ret);
return 0;
}
```

The running result of the code is:

Features and precautions of strcat function:

• 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 of strcat function

``` char *my_strcat(char *dest, const char*src)//Ensure that the source string is not modified
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while(*dest)
{
dest++;//Arrive at the \ 0 address of the destination string first
}
while((*dest++ = *src++))//Dereference first and then + +, so the \ 0 in the source string can be appended at last
{
;
}
return ret;
}
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abcd";
char str2[] = "efgh";
char* ret = my_strcat(str1, str2);
printf("%s", ret);
return 0;
}
```

Code execution result:

# 5, strcmp function (string comparison)

## Introduction to strcmp function

The return value type of the strcmp function is int. the first parameter is the address of the first letter of a string, and the second parameter is the address of the first letter of another string. The strcmp function compares the contents of the string, not the length of the string.

For the return value of strcmp function, C language specifies that if the content of the first string is less than that of the second string, it will return a value less than 0; if the content of the first string is equal to that of the second string, it will return 0; if the content of the first string is greater than that of the second string, it will return a value greater than 0.

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcd";
char str2[] = "abc";
int ret = strcmp(str1, str2);
printf("%d", ret);
return 0;
}
```

Code running results: (although the returned values greater than 0 are all 1, the returned values greater than 0 specified by each compiler are different here, and there will be differences here).

If the strcmp function is compared in the above example, and the string content is not clear enough, the following examples can be better observed:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcd";
char str2[] = "abq";
int ret = strcmp(str1, str2);
printf("%d", ret);
return 0;
}
```

Code run result:

## Simulation Implementation of strcmp function

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

my_strcmp(const char* s1, const char* s2)
{
assert(s1 && s2);
while (*s1 == *s2)
{
if (*s1 == '\0')
return 0;
s1++;
s2++;
}
return *s1 - *s2;//Compare string contents
}

#include <string.h>
int main()
{
char str1[] = "abcd";
char str2[] = "abq";
int ret = my_strcmp(str1, str2);
printf("%d", ret);
return 0;
}
```

Code run result:

strcpy, strcat and strcmp are string functions with unlimited length, so they are not safe enough. Therefore, there are strncpy, strncat and strncmp functions.

# 6, strncpy function (restricted string copy)

## Introduction to strncpy function

The return value type of strncpy function is char * type. The first parameter of the function is the initial address of the destination string, the second parameter is the initial address of the source string, and the third parameter is the number of characters to be copied in the past.

Header file required to use strncpy function:

Use of strncpy:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "abcd";
char str2[] = "kpl";
char* ret = strncpy(str1, str2, 2);
printf("%s", ret);
return 0;
}
```

Code run result:

## Simulation Implementation of strncpy function

```#include <stdio.h>
#include <string.h>
char* my_strncpy(char* dest, char* src, size_t count)
{
while (count--)//First use count and then subtract 1
{
*(dest + count) = *(src + count);
}
return dest;
}
int main()
{
char str1[20] = "abcd";
char str2[] = "kpl";
char* ret = my_strncpy(str1, str2, 2);
printf("%s", ret);
return 0;
}
```

# 7, strncat function (restricted string append)

## Introduction to strncat function

The return value types and parameters of strncat function and other restricted library functions are almost the same, which will not be described here.

Header file required to use strncat function:

## Simulation Implementation of strncat function

```#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strncat(char* dest, char* src, size_t count)
{
assert(dest && src);
char* ret = dest;
while (*dest)
{
dest++;//To the \ 0 position of the destination string
}
while (count--)
{
*(dest + count) = *(src + count);//String append
}
return ret;
}
int main()
{
char str1[20] = "abcd";
char str2[] = "kpl";
char* ret = my_strncat(str1, str2, 2);
printf("%s", ret);
return 0;
}
```

# 8, strncmp function (restricted string content comparison)

## Introduction to strncmp function

The return value type of strncmp function is int, and the return value rules are the same as those of strcmp function, which will not be discussed in detail here. The first and second parameters: because the two strings are only used for comparison, if modified, they do not meet the use rules of strncmp function. Therefore, const is added in front of the first two parameters to ensure that the string content is not modified. The third parameter is the character of comparison number.

Header file required to use strncmp function:

Use of strncmp function:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcd";
char str2[] = "abkl";
int ret = strncmp(str1, str2, 2);
printf("%d", ret);
return 0;
}
```

Code run result:

## Simulation Implementation of strncmp function

```#include <stdio.h>
#include <assert.h>
#include <string.h>
int my_strncmp(char* s1, char* s2, size_t count)
{
assert(s1 && s2);
while (count--)
{
if (*s1 == *s2)
{
s1++;
s2++;
}
}
return *s1 - *s2;
}
int main()
{
char str1[] = "abcd";
char str2[] = "abkl";
int ret = my_strncmp(str1, str2, 2);
printf("%d", ret);
return 0;
}
```

Code execution result:

# 9, strstr function (string lookup function)

The return value type of strstr function is char type. The first parameter is the string to be searched, and the second parameter is the string to be searched in the first parameter. For example, if the first string is i am a student and the second string is a, the returned char type will print the result in the form of character string as am a student.

Header file required to use STR function:

Use of STR function:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcdefdgh";
char str2[] = "d";
char* ret = strstr(str1, str2);
printf("%s", ret);
return 0;
}
```

Code execution result:

## Simulation Implementation of STR function

```#include <stdio.h>
#include <string.h>
char* my_strstr(const char* str1, const char* str2)
{
char* s1, * s2;
char* cp = str1;
if (*str2 == '\0')
{
return str1;
}
while (*cp)
{
s1 = cp;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)//Start traversal search
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;
}
cp++;//When different characters are found during character search, the search starts from the next character at the beginning of the search
}
return NULL;
}
int main()
{
char str1[] = "abcdefdgh";
char str2[] = "d";
char* ret = my_strstr(str1, str2);
printf("%s", ret);
return 0;
}
```

Code execution result:

There are two ways to find a string:
The first method: for example, if you find cd in the abcd string, you can find the two strings one by one.

The second: you need to traverse several times to find it.

When the character c is found in the first traversal, it is found that there is no bbc string in the searched string, but there are actually some strings in the searched string, so you only need to traverse again. And start looking at the next character.

# 10, strtok function (for string segmentation)

The return value type of strtok function is char *, that is, the address of the returned string. The first is used to store the string address to be divided, and the second is used to store the set address of the separator.

Use of strtok function:

```#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "by@bite.cn";
char str2[200] = { 0 };
char sep[] = "@.";
strcpy(str2, str1);
char* ret = NULL;
for (ret = strtok(str2, sep); ret != NULL; ret = strtok(NULL, sep))
{
printf("%s ", ret);
}
}
```

Note:

• 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 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.

Since the strtok function is rarely used, there is no Simulated Implementation of strtok here

# 11, strerror (error message report)

The return value type of strerror function is char *, and the parameter is int.

Use of strerror function:

```#include <stdio.h>
#include <string.h>
int main()
{
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("Error opening file unexist.ent: %s\n", strerror(errno));
//errno: Last error number
return 0;
}
```

# 12, memcpy function (memory copy function and memory does not overlap)

## Existence and significance of memcpy function

Because strcpy and strncpy functions are copies between strings, they are not applicable to other types of copies such as integers and structures. Therefore, the copy of memcpy function occurs automatically.

## Introduction to memcpy function

Because it enables copying between multiple same types, the return value of the memcpy function is void * type, and the first parameter is also void * type, which is the copied address; The second parameter is also void *, which is the address of the content to be copied; The third parameter is size_t (unsigned integer), where count is the size of the entire element to be copied (unit: bytes).

Use of memcpy function:

```#include <stdio.h>
#include <string.h>
int main()
{
int arr1[100] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[100] = { 0 };
int i = 0;
memcpy(arr2, arr1, 10 * sizeof(int));//The size of arr1 is 40 bytes, which can be calculated by sizeof
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
```

Code run result:

Characteristics of memcpy function:

• 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 of memcpy function

```#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dst, const void* src, size_t count)
{
void* ret = dst;
assert(dst);
assert(src);
while (count--) {
*(char*)dst = *(char*)src; //Copy one byte at a time
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return(ret);
}
int main()
{
int arr1[100] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[100] = { 0 };
int i = 0;
my_memcpy(arr2, arr1, 10 * sizeof(int));
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
```

Code run result:

In this program, two arrays without memory overlap are copied to each other, but in the case of memory overlap, the memcpy function cannot be implemented in some compilers, so we introduce the memmove function below.

# 13, memmove function (memory copy function and can solve memory overlap)

## Introduction to memmove function

Header file required to use memmove function:

The return value and parameters of the memmove function are the same as those of the memcpy function, which will not be discussed in detail here.

## Simulation of memmove function

```#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memmove(void* dst, const void* src, size_t count)
{
void* ret = dst;
assert(dst);
assert(src);
if (src > dst)
{
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
while (count--)
{
*((char*)dst + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
my_memmove(arr1+4,arr1+2 ,16);
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
```

Code execution result:

If we simulate the code implementing the memcpy function, the result is:

It can be seen that there are three consecutive times 3 and 4 here. What is the reason?

Copying from front to back means that the memory content to be copied is copied from front to back, that is, from 3 to 6. If copying from back to front, it is copied from 6 to 3. Because 5 and 6 are assigned values of 3 and 4 before copying, the contents of 3 and 4 are still copied at positions 5 and 6.

So what are the situations? How?
There are three situations:

We found that when src is greater than dst, it can only be copied from front to back, otherwise the error result of the above execution with memcpy function will appear. When src is less than dst, it can only be copied from back to front, and the copied memory content is also copied from back to front. In the third case, when dst is greater than src and there is no memory content overlap, it is possible to copy from front to back or from back to front. Therefore, we can use two solutions to solve these three cases. Understanding the following code in the memmove simulation function is critical.

```if (src > dst)
{
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else
{
while (count--)
{
*((char*)dst + count) = *((char*)src + count);//count has been reduced by 1 inside the loop, just to the last value of the content that needs to be copied most
}
}
```