Character functions, string functions and memory manipulation functions in C language

Preface

Characters and strings are processed frequently in C language, but C language itself does not have a string type. Strings are usually placed in constant strings or character arrays . String constants are suitable for string functions that do not modify it.

1. Introduction to library functions

Find the length of a string

  • strlen
    string function with unlimited length
  • strcpy
  • strcmp
  • strcat
    length-limited string function
  • strncpy
  • strncmp
  • strncat
    string search
  • strstr
  • strtok
    error message report
  • sterror
  • perror

Character classification function
insert image description here

Memory operation function

  • memcpy
  • memcmp
  • memmove
  • memset

strlen

size_t strlen ( const char * str );

Definition: Find the length of a string
Header file: <string.h>

Note:

  • The string uses '\0' as the end mark, and 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'.
  • The return value of the function is size_t (unsigned)

example:

#include<stdio.h>
#include<string.h>
 
int main()
{
    
    
	char arr[] = "hello world";
	
	printf("%d\n", strlen(arr));
 
	return 0;
}

strcpy

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

Definition: Copy string
Header file: <string.h>

Note:

  • The function of the strcpy function is to copy strSource (including the terminating null character) to the location specified by strDestination. No overflow check is performed when copying or appending strings (you need to determine by yourself that strDestination space >= strSource space).
  • strSource: source string strDestination target string
  • The source string must end with '\0'.
  • The target space must be large enough to accommodate the source string.
  • The target space must be variable
  • Simple understanding is to copy the content pointed by the original pointer to the space of the target pointer
  • The role of Char* here is: when copying the source data, we expect that the target space will change and the contents of the target space may be used, so what needs to be returned is the starting address of the target space.
  • const: Both the variable and the file itself have read and write permissions. When modified by const, the permissions of the variable are reduced, so that the variable can only be read but not written. It is also to improve the security of the code.

example:

#include<string.h>
#include<stdio.h>
 
int main()
{
    
    
	char arr1[] = "abcdef";
	char arr2[] = "xxxxxx";
	
	strcpy(arr2, arr1);
 
	printf("%s\n", arr2);
 
	return 0;
}

strcmp

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

Definition: Compare strings
Header file: <string.h>
Note:

  • The standard stipulates:
    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 greater than 0 is returned. Number less than 0

  • What is compared is not the length of the string.
    Compare the size/asscii code value of the characters at the corresponding positions of the string.
    If they are the same, compare the next pair until they are different or encounter \0
    . Example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[] = "abcdef";
	char arr2[] = "abcdfg";

	printf("%d\n", strcmp(arr1, arr2));

	return 0;
}

screwed up

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

Definition: Append string
Header file: <string.h>

Note:

  • Parameters: strDestination: destination string ending with \0
    strSource: source string ending with \0
  • The source string must end with '\0'.
  • The destination space must be large enough to hold the contents of the source string.
  • The target space must be modifiable.
  • The strcat function appends strSource to strDestination and terminates the string with a null character. The initial character of strSource overrides the terminating NULL character of strDestination. No overflow checking is performed when copying or appending strings. The behavior of strcat is undefined if the source and destination strings overlap.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[20] = "abc";
	char arr2[] = "def"; 

	printf("%s\n", strcat(arr1, arr2));

	return 0;
}

strncpy

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

Definition: Copy string
Header file: <string.h>

Note:

  • count: number of characters to copy
  • Copies num characters from source string to destination 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.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[] = "abcdef";
	char arr2[] = "xxxxxx";

	printf("%s\n", strncpy(arr2, arr1, 3));

	return 0;
}

strncmp

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

Definition: Compare two strings
Header file: <string.h>

Note:

  • Compare until another character is different or a string ends or all count characters are compared

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[20] = "ab";
	char arr2[] = "abcdef";

	printf("%d\n", strncmp(arr1, arr2, 3));

	return 0;
}

strncat

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

Definition: Append string
Header file: <string.h>

Note:

  • The strncat function appends at most the first count characters of strSource to strDest. The initial character of strSource overrides the terminating null character of strDest. If a null character appears in strSource before count characters are added, strncat will append all the characters in strSource up to the null character. If count is greater than the length of strSource, the length of strSource is used instead of count. The resulting string is null-terminated. If copying occurs between overlapping strings, the behavior is undefined.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[20] = "abc";
	char arr2[] = "def"; 

	printf("%s\n", strncat(arr1, arr2,1));

	return 0;
}

To sum up, it can be summarized as follows:
insert image description here
strstr

char *strstr( const char *string, const char *strCharSet );

Definition: Find substrings.
Header file: <string.h>

Note:

  • Each of the functions 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 zero-length string, string is returned.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[] = "abcdef";
	char arr2[] = "cdef";

	printf("%s\n", strstr(arr1, arr2));

	return 0;
}

strtok

char * strtok ( char * str, const char * sep );

Definition: Find the next token in a string / Split a string by special symbols in a string
Header file: <string.h>

Note:

  • The sep parameter is a string that defines the set of characters used as separators
  • The first parameter specifies a string containing zero or more tokens separated by one or more delimiters in the sep string.
  • 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 manipulated string, so the string split using 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 token in str, and the strtok function will save its position in the string.
  • The first parameter of the strtok function is NULL, and the function will start at the saved position in the same string and find the next token.
  • Returns a NULL pointer if there are no more tokens in the string.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char arr1[] = "[email protected]";

	char buf[20] = {
    
     0 };

	strcpy(buf, arr1);

	const char* sep = "@.";


	//写法①
	printf("%s\n", strtok(buf, sep));
	printf("%s\n", strtok(NULL, sep));
	printf("%s\n", strtok(NULL, sep));

	//写法②
	char* str = NULL;
	for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep))
	{
    
    
		printf("%s\n", str);
	}

	//strtok会从字符串首字符开始寻找,找到分隔符后,会把分隔符置成\0(NULL),并取出首字符到\0之前的元素
	//下次访问的时候会从NULL的位置继续向后访问,直至再次访问到分割符,置成NULL,取出
	//其中,strtok的实现应该是有一个静态变量的指针保存着NULL的位置

	return 0;
}

strerror

char * strerror ( int errnum );

Definition: return error code, corresponding error message
header file: <string.h>

Note:

  • strerro returns a pointer to the error message string.
  • strerror will not print a message, and you need to call an output function, such as printf.

example:

#include<stdio.h>
#include<string.h>
#include<errno.h>

int main()
{
    
    

	strerror(errno);//errno(错误码):全局变量 ,需要头文件<errno.h>

	//补:
    // 0 :No error   无错误信息
    // 1 :Operation not permitted  操作被拒绝
    // 2 :No such file or directory 无文件
    // 3 :No such process  无进程
    // 4 :Interrupted function call 函数调用中断
    //...

	return 0;
}

perror

void perror( const char *string );

Definition: Print error information
Header file: <stdio.h> or <stdlib.h>

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    

    perror("自定义提示信息");

    return 0;
}

You can briefly take a look at the comparison between perror vs strerror:
insert image description here
- memcpy

void *memcpy( void *dest, const void *src, size_t count );

Definition: Copy characters between buffers
Header file: <string.h>
Note:

  • The function memcpy copies count bytes of data starting from the location of src to the memory location of dest.
  • This function does not stop when it encounters '\0'.
  • If there is any overlap between src and dest, the results of the copy are undefined.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5,6,7 };

	int arr2[20] = {
    
     0 };

	memcpy(arr2, arr1, 20);//单位是字节

	return 0;
}

- memcmp

int memcmp ( const void * ptr1, 
 const void * ptr2, 
 size_t num );

Definition: Compare characters in two buffers
Header file: <string.h>
Note:

  • Compare num bytes starting from the ptr1 and ptr2 pointers

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5,6,7 };

	int arr2[20] = {
    
     1234560x00000007 };

	memcmp(arr2, arr1, 20);//单位是字节

	return 0;
}

- memmove

void * memmove ( void * destination, const void * source, size_t num );

Definition: move one buffer to another header
file: <string.h>
Note:

  • The difference with memcpy is that the source memory block and target memory block processed by the memmove function can overlap.
  • If the source space and the target space overlap, you have to use the memmove function to deal with it.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5,6,7 };

	memmove(arr1+3, arr1, 20);//可以实现重叠内存的拷贝

	return 0;
}

- memset
definition: set the buffer to the specified character/initialization
Header file: <string.h>
Note:

  • The memset function sets the first count byte of dest to the character c.

example:

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	int arr[] = {
    
     0x11111111,0x22222222,3,4,5 };

	memset(arr, 0, 20);//将arr前20个字节初始化成0

	return 0;
}

2. Function simulation implementation

- strlen

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

int my_strlen(char* str)
{
    
    
	assert(str);

	int count = 0;

	while (*str)
	{
    
    
		count++;
		str++;
	}

	return count;
}

int main()
{
    
    
	char arr[] = "abcdef";

	printf("%d\n", my_strlen(arr));

	return 0;
}

- strcpy

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

char* my_strcpy(char* dest, const char* sour)
{
    
    
    assert(dest && sour);

    char* str = dest;

    while (*dest++ = *sour++)
    {
    
    
        ;
    }

    return str;
}

int main()
{
    
    
    char arr1[] = "xxxxxxxxxxx";
    char arr2[] = "abcdef";

    printf("%s\n", my_strcpy(arr1, arr2));

    return 0;
}

- strcmp

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

int my_strcmp(const char* str1, const char* str2)
{
    
    
    assert(str1 && str2);

    while (*str1 == *str2)
    {
    
    
        if (*str1 != '\0')
        {
    
    
            return 0;
        }
        str1++;
        str2++;
    }

    return *str1 - *str2;
}

int main()
{
    
    
    char arr1[] = "abcdef";
    char arr2[] = "bcdefg";

    printf("%d\n", my_strcmp(arr1, arr2));

    return 0;
}

- screwed up

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

char* my_strcat(char* dest, char* sour)
{
    
    
    assert(dest && sour);

    char* str = dest;
    
    while (*dest)
    {
    
    
        dest++;
    }

    while (*dest++ = *sour++)
    {
    
    
        ;
    }
    
    return dest;
}

int main()
{
    
    
    char arr1[10] = "abc";

    char arr2[] = "def";

    my_strcat(arr1, arr2);

    printf("%s\n", arr1);

    return 0;
}

- strstr

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

char* my_strstr(const char* str1, const char* str2)
{
    
    
    assert(str1 && str2);

    const char* s1 = str1;
    const char* s2 = str2;

    const char* cur = str1;

    while (*cur)
    {
    
    
        s1 = cur;
        s2 = str2;

        while (*s1 && *s2 && (*s1 == *s2))
        {
    
    
            s1++;
            s2++;
        }

        if (*s2 == '\0')
        {
    
    
            return (char*)cur;
        }

        cur++;
    }

    return NULL;
}

int main()
{
    
    
    char arr1[] = "abcdef";
    char arr2[] = "cde";

    char* str = my_strstr(arr1, arr2);

    if (str == NULL)
    {
    
    
        printf("NO\n");
    }
    else
    {
    
    
        printf("YES\n");
    }

    return 0;
}

- memcpy

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

void* my_memcpy(void* dest, const void* sour, size_t count)
{
    
    
	assert(dest && sour);

	void* ret = dest;

	while (count--)
	{
    
    
		*(char*)dest = *(char*)sour;
		dest = (char*)dest + 1;
		sour = (char*)sour + 1;
	}

	return dest;
}

int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int arr2[12] = {
    
     0 };

	int sz = sizeof(arr2) / sizeof(arr2[0]);

	my_memcpy(arr2, arr1, 20);//size_t 单位是字节

	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr2[i]);
	}

	return 0;
}

- memove

Idea:
insert image description here

void* my_memove(void* dest, const void* sour, size_t count)
{
    
    
	assert(dest && sour);

	void* ret = dest;

	if (dest < sour)
	{
    
    
		//前->后
		while (count--)
		{
    
    
			*(char*)dest = *(char*)sour;
			dest = (char*)dest + 1;
			sour = (char*)sour + 1;
		}
	}
	else
	{
    
    
		//后->前
		while (count--) //这里 count==20 为真 进入循环,又因为是后置-- ,所以count == 19 
		{
    
    
			*((char*)dest + count) = *((char*)sour + count); //这里每次进来count都会 --
		}
	}

	return ret;

}

int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	              //1 2 1 2 3 4 5 8 9 10

	my_memove(arr + 2, arr, 20);//可以实现重叠内存的拷贝

	int sz = sizeof(arr) / sizeof(arr[0]);

	int i = 0;
	for (i = 0; i < sz; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/m0_73969113/article/details/130909224