Introduction and Simulated Realization of C Language String Functions and Memory Functions

0. Preface

The processing of characters and strings in C language is very frequent, but C language itself does not have a string type, and strings are usually placed in constant strings or character arrays . String constants apply to string functions that do not modify them.

1. Introduction and simulation of string functions

  • The C language itself has some library functions, so if you see a function that others don’t know, you can check it on this website, and remember to quote the corresponding header file when using the library function

    [Reference - C++ Reference]:

1.1 strl

Function to find the number of strings

For example

int main()
{
    char arr1[] = "abcdef";
    int ret = strlen(arr1);
    printf("%d\n", ret);
    return 0;
}

operation result

 

size_t strlen ( const char * str );

  • The string has '\0' as the end mark, and the strlen function returns the number of characters that appear before '\0' in the string (not including ').

  • size_t strlen ( const char * str );

  • 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

  • Simulate it yourself

// Implemented in the form of a calculator
size_t my_strlen(const char* str)
{
    int count = 0;
    while (*str != '\0')
    {
        count++;// Count the number of characters before '\0'
        str++;
    }
    return count;
}
// implement recursively
size_t my_strlen(const char* str)
{
    if (*str == '\0')
        return 0;
    else
        return 1 + my_strlen2(str + 1);
}

1.2 strcpy

char* strcpy(char * destination, const char * source );

The string copy function can give you two strings, you can put a string in another space

For example

int main()
{
    char arr1[] = "hello world!";
    char arr2[20] = { 0 };
    strcpy(arr2, arr1);
    printf("%s\n", arr2);
    return 0;
}

operation result

 

  • The source string must end with '\0' as a character

  • Will place a copy of '\0' of the source string into the target space

  • target space must be mutable

  • The space in the target space must be large enough to fit in the target space

  • Simulate it yourself

Analog implementation of the strcpy function

#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
    assert(dest && src);
    char* ret = dest;
    while (*dest != *src)
    {
        *dest = *src; // Assign the character of src to dest
        dest++;
        src++;
    }
    return ret;
}

In fact, we understand the judgment of the while loop and can make the code simpler, and directly assign the value of src to dest in the judgment part of the while loop.

When the value of src finds '\0' and assigns it to dest, the while loop will stop and copy all the characters in src to dest

char* my_strcpy(char* dest, const char* src)
{
    assert(dest && src);
    char* ret = dest;
    while (*dest++ = *src++)
    {
        ;
    }
    return ret;
}

1.3 cracked

char * strcat ( char * destination, const char * source );

String append function, which can append another string in a string

For example

int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world!";
    strcat(arr1, arr2);
    printf("%s\n", arr1);
    return 0;
}

operation result

  • The source string must be terminated with '\0'.

  • The destination space must be large enough to hold the contents of the source string.

  • The target space must be modifiable.

  • Can the string be appended to itself?

  • The answer is no, because adding to yourself will overwrite '\0', '\0' is the sign of the end of the string, and you can't stop if you overwrite and append '\0'

Analog implementation of strcat

char* my_strcat(char* dest, const char* src)
{
    assert(dest && src);
    char* ret = dest;
    // find target'\0'
    while (*dest != '\0')
    {
        dest++;
    }
    // copy to target space
    while (*dest++ = *src++)
    {
        ;
    }
    
    return ret;
}

1.4 strcmp

int strcmp ( const char * str1, const char * str2 );

String comparison function, if the characters in arr1 are greater than the characters in arr2, return the number >0, if the characters in arr1 are smaller than the characters in arr2, return the number <0,

If the character in arr1 is equal to the character in arr2 returns = 0.

For example

int main()
{
    char arr1[] = "abcd";
    char arr2[] = "abc";
    int ret = strcmp(arr1, arr2);
    printf("%d\n", ret);
    return 0;
}

Results of the

 

 

standard regulation

  • If the first string is greater than the second string, return a number greater than 0

  • If the first string is equal to the second string, return 0

  • The first string is less than the second string, returns a number less than 0

Analog implementation of strcmp

int my_strcmp(const char* str1, const char* str2)
{
    assert(str1 && str2);
    while (*str1 == *str2)
    {
        if (*str1 == '\0')
           return 0;
        str1++;
        str2++;
    }
    
    if (*str1 > *str2)
        return 1;
    else
        return -1;
    return *str1 - *str2;
}

1.5 strncpy

char * strncpy ( char * destination, const char * source, size_t num );

Similar to the function of the strcpy function, n represents num, which can specify the number of copied strings

For example

int main()
{
    char arr1[] = "hello world!";
    char arr2[20] = { 0 };
    strncpy(arr2, arr1,5);
    printf("%s\n", arr2);
    return 0;
}

Results of the

 

char * strncat ( char * destination, const char * source, size_t num );
  • Copy num characters from source string to target space

  • If the length of the source string is less than num, after copying the source string, add 0 to the end of the target until num.

1.6 strncat

char * strncat ( char * destination, const char * source, size_t num );

Similar to the function of strcat, n also means num, append num characters to the target space

For example

int main()
{
    char arr1[20] = "hello ";
    char arr2[] = "world!";
    strncat(arr1, arr2,6);
    printf("%s\n", arr1);
    return 0;
}

Results of the

 

1.7 strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

Similar to the function of strcmp, you can specify to compare num characters

For example

int main()
{
    char arr1[] = "abcd";
    char arr2[] = "abce";
    int ret = strncmp(arr1, arr2,4);
    printf("%d\n", ret);
    return 0;
}

Results of the

 

int strncmp ( const char * str1, const char * str2, size_t num );
  • Compare until another character is different or a string ends or all num characters are compared.

1.8 strstr

  char * strstr (const char * str1, const char * str2 );

A function to find a substring, if there is a substring, the entire string will be printed out

For example

int main()
{
    char arr1[] = "abcdefg";
    char arr2[] = "abc";
    char* p = strstr(arr1, arr2);
    if (*p == NULL)
    {
        printf("Can't find\n");
    }
    else
    {
        printf("%s\n", p);
    }
    return 0;
}

Results of the

 

Analog implementation of the strstr function

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

1.9 strtok

char * strtok ( char * str, const char * delimiters );
  • delimiters is the delimiter, which divides the long string into multiple short strings according to the delimiter

  • The parameter of delimiters contains 0 or more delimiters

  • The strtok function finds the next token in str, terminates it with \0, and returns a pointer to this token.

  • (Note: The strtok function will change the string being manipulated, so the strings split using the strtok function are generally temporary copied content and can be modified.)

  • The first parameter of the strtok function is not NULL, the function will find the first mark in str, and the strtok function will save its position in the string.

  • The first parameter of the strtok function is NULL, the function will start at the saved position in the same string, and search for the next token.

  • Returns a NULL pointer if there are no more tokens in the string.

Divide a long string into multiple substrings according to the delimiter

For example

int main()
{
    char arr[] = "192.168.222.33";
    char buf[30] = { 0 };
    strcpy(buf, arr);
    const char* p = ".";
    char* str = strtok(buf, p);
    printf("%s\n", str);
    str = strtok(NULL, p);
    printf("%s\n", str);
    str = strtok(NULL, p);
    printf("%s\n", str);
    str = strtok(NULL, p);
    printf("%s\n", str);
    return 0;
}

Results of the

 

2.0 strerror

Error code return information function, this function can return an error message as long as you give him an error code

For example

int main()
{
    char* str = strerror(0);
    printf("%s\n", str);
    str = strerror(1);
    printf("%s\n", str);
    str = strerror(2);
    printf("%s\n", str);
    str = strerror(3);
    printf("%s\n", str);
    str = strerror(4);
    printf("%s\n", str);
    return 0;
}

Results of the

 

2.1 memcpy

void * memcpy ( void * destination, const void * source, size_t num );
  • The memcpy function copies num bytes of data backwards from the source to the destination.

  • This function does not stop when encountering '\0'

  • If there is any overlap between source and destination, the result of the copy is unknowable

The memory copy function has two spaces, and can put the contents of one space into another.

For example

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

Results of the

 

Here put the contents of the arr1 array into the arr2 array

Analog implementation of the memcpy function

void* my_memcpy(void* dest, const void* src, size_t num)
{
    assert(dest && src);
    void* ret = dest;
    while (num--)
    {
        *(char*)dest = *(char*)src;// Convert dest to (char*) and then dereference, the same is true for src
        dest = (char*)dest + 1;// Move the original position of dest back
        src = (char*)src + 1; // Move the original position of src back
    }
    return ret;
}

2.2 memmove

void * memmove ( void * destination, const void * source, size_t num );
  • The difference between memcpy and memmove is that the memmove function handles that the source memory block and the target space memory block can overlap

  • If the source memory block and the target space memory block overlap, you need to use the memmove function

For example

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

Put the content of arr1 backward 12 bytes into arr1, that is, cover 1, 2, 3 with 4, 5, 6, and then the content behind remains unchanged

Results of the

 

Simulation implementation of memmove function

void* my_memmove(void* dest, const void* src, size_t num)
{
    assert(dest && src);
    void* ret = dest;
    if (dest < src)
    {
        while (num--)
        {
            // forward and backward
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }
    else
    {
        // back to front
        while (num--)
        {
            *((char*)dest + num) = *((char*)src + num);
        }
    }
    return ret;
}

This is divided into two cases. When dest<src, copy from front to back, and when dest>src, copy from back to front. The comparison here is the position, which can be seen from the drawing

dest<src

 

dest>src

 

2.3 memcmp

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • Compare num bytes starting from ptr1 and ptr2 pointers

  • The return value is as follows

 

Example of use

int main()
{
    int arr1[] = { 1,2,3,4,6 };
    int arr2[] = { 1,2,3,4,5 };
    int ret = memcmp(arr1, arr2, 17);
    printf("%d\n", ret);
}

Results of the

 

Here we will not take everyone to simulate the implementation, and those who are interested can study it by themselves.

Guess you like

Origin blog.csdn.net/weixin_64214213/article/details/130833139