⭐ Mid Autumn Festival meeting advanced C language ⭐ String function and memory function [recommended collection]

catalogue

preface

Summary of string functions and memory functions (explained)

Introduction to string functions

strlen (string length calculation function)

Strcpy / strncpy (string copy function)

Strcat / strncat (string splicing function)

StrCmp / strncmp (string comparison function)

strstr (string lookup function)

strtok (string slicing function)

StrError (a string function that returns a description of the cause of the error)

Introduction to memory functions

memcpy (memory copy function)

memmove (memory move function)

memcmp (memory comparison function)

preface

This chapter mainly explains:

  • Use and precautions of character and string library functions

Summary of string functions and memory functions (explained)

  • Find string length: strlen
  • String function with unlimited length: strcpy strcat strcmp
  • String function with limited length: strncpy strncat strncmp
  • String lookup: STR strtok
  • Error message report: strerror
  • Memory operation function: memcpy, memmove, memset, memcmp

Words written before:

C language itself has no string type

Strings are usually processed in constant strings (without modification) or character arrays (which can be modified)

Introduction to string functions

strlen (string length calculation function)

  • definition:
size_t strlen ( const char * str );
  • be careful:
  1. String with  '\ 0 'as the end flag, the strlen function returns the number of characters that appear before' \ 0 'in the string (excluding' \ 0 ')
  2. The parameter is a character pointer and is a pointer to a string that must end with '\ 0' (otherwise an error will occur)
  3. Size_t is defined as typedef unsigned int size_t; that is, the return type of strlen function is unsigned integer
  • Error prone questions:
#include <stdio.h>
#include <string.h>
int main()
{
	const char* str1 = "abcdef";
	const char* str2 = "abc";
	if (strlen(str2) - strlen(str1) > 0)
	{
		printf("ha-ha\n");
	}
	else
	{
		printf("ha-ha\n");
	}
	return 0;
}
//Output result: hehe
//Explanation: the strlen function returns an unsigned integer, the addition and subtraction of an unsigned number, or an unsigned number (always greater than 0)
  • Function demonstration:
#include<stdio.h>
#include<string.h>
int main()
{
	char ch[] = "abcdef";
	printf("%d\n", strlen(ch));
	return 0;
}
//Output result: 6
  • Simulation Implementation:
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
//For the incoming pointer and we want to modify the content of the object it points to, we can use const to modify it
{
	assert(str);//The incoming pointer cannot be NULL. Remember to include the header file < assert. H >
	size_t len = 0;
	while (*str++)//*The priority of is higher than the post + +. If it is' \ 0 ', it will not enter the loop (' \ 0 'ASCII code value is 0)
	{//Post entry pointer str++
		len++;
	}
	return len;
}

Strcpy / strncpy (string copy function)

  • definition:
char *strcpy( char *strDestination//Target string / /, 
const char *strSource//Source string);
char *strncpy( char *strDest, const char *strSource, size_t count//Copy length (in bytes);
  • difference:

strcpy: copy all the way to '\ 0' (including '\ 0') (not safe)

strncpy: the parameter count is used to control the length of the copied string (if it exceeds the length of the source string, 0 will be added after copying) (relatively safe)

  • be careful:
  1. The source string must end with '\ 0'
  2. The target space must be large enough (to ensure that the source string can be stored) and must be modifiable
  • Function demonstration:
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "Hello world!";
	char str2[20] = { 0 };
	char str3[20] = { 0 };
	strcpy(str2, str1);
	strncpy(str3, str1, 2);
	printf("%s\n", str2);
	printf("%s\n", str3);
	return 0;
}
//Output results:
//Hello world!
//He
  • Simulation Implementation:
char* my_strcpy(char* des, const char* src)
{
	assert(des&&);//Pointer is not NULL
	char* ret = des;//Address of the first element of the record string
	while (*des++ = *src++)//First assign the * pointer, then judge the content pointed by des, and then assign the pointer++
	{
		;
	}
	return ret;//Returns the address of the first element of a string
}
#include<assert.h>
char* my_strncpy(char* des, const char* src, int n)
{
	assert(des && src);
	char* ret = des, *cp = (char*)src;
	int count = 0;
	while (*cp++)//Calculate source string length
	{
		count++;
	}
	for (int i = 0; i < n; i++)
	{
		if (i < count)
		{
			*des++ = *src++;
		}
		else//If the number of copies is greater than the length, add 0
		{
			*des++ = '0';
		}
	}*des = '\0';//End with Terminator
	return ret;
}

Strcat / strncat (string splicing function)

  • definition:
char *strcat( char *strDestination, const char *strSource );
char *strncat( char *strDest, const char *strSource, size_t count );
  • difference:

strcat: splice the source string to the end of the destination string (starting from '\ 0' of the destination string and splicing to '\ 0' of the source string, including '\ 0')

strncat: the parameter count is used to control the number of spliced characters (greater than the number of source strings, and only spliced to '\ 0' of the source string)

  • be careful:
  1. The source string must end with '\ 0'
  2. The target space must be large enough (to ensure that spliced characters can be stored) and must be variable

Function demonstration:

#include <stdio.h>
#include <string.h>
int main()
{
	char str1[100] = "hello ";
	char str2[100] = "hello ";
	char str3[] = "world!";
	strcat(str1, str3);
	strncat(str2, str3, 4);
	printf("%s\n", str1);
	printf("%s\n", str2);
	return 0;
}
//Output results:
//hello world!
//hello worl
  • Simulation Implementation:
char* my_strcat(char* des, const char* str)
{
	assert(des && str);
	char* ret = des;
	//Find des last character
	while (*des)
	{
		des++;
	}
	//Copy the string in str to the end of des
	while (*des++ = *str++)
	{
		;
	}
	return 0;
}
char* my_strncat(char* des, const char* str, size_t n)
{
	assert(des && str);
	char* ret = des;
	while (*des)
	{
		des++;
	}
	for (size_t i = 0; i < n && *str; i++)
	{
		*des++ = *str++;
	}
	*des = '\0';//Append terminator at the end
	return ret;
}

StrCmp / strncmp (string comparison function)

  • definition:
int strcmp( const char *string1, const char *string2 );
int strncmp( const char *string1, const char *string2, size_t count );
  • difference:

strcmp: compare the size of ASCII code value corresponding to each character

strncmp: the parameter count controls the number of comparison characters (the number of comparison characters does not exceed the number of two strings (including '\ 0'), whichever is less)

  • Standard provisions:

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 less than 0 is returned

  • be careful:

Another character is different, or a string ends, or count characters are all compared

  • Function demonstration:
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "abcd";
	char str2[] = "abcd";
	char str3[] = "accd";
	printf("%d\t", strcmp(str1, str2));
	printf("%d\t", strcmp(str1, str3));
	printf("%d\t", strncmp(str1, str2,2));
	printf("%d\t", strncmp(str1, str3,2));
	return 0;
}
//Output result: 0 - 1
  • Simulation Implementation:
int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
//If the characters are equal, the next one is compared. If two characters are not equal in the middle, the traversal ends
	while (*str1 && *str2 && *str1 == *str2)
	{
		str1++;
		str2++;
	}
//The result returns the difference between the two ASCII codes
	return (*str1 - *str2);
}
int my_strncmp(const char* str1, const char* str2, size_t n)
{
	assert(*str1 && *str2);
	for (size_t i = 0; i < n - 1  && *str1 && *str2; i++)
	{
//Not at the same time, end directly, and then return to the difference between the two at the moment
		if (*str1 != *str2)
			break;
		str1++;
		str2++;
	}
//Or directly compare the last character after traversal (n-1 times)
	return (*str1 - *str2);
}

strstr (string lookup function)

  • definition:
char *strstr( const char *string, const char *strCharSet );

Note: if the string strCharSet appears in a string, the first address of the string for the first time in the string is returned; otherwise, NULL is returned

  • Simulation Implementation:
  1. First, find the same character as the first character of str2 in str1, and then compare the characters after str2 one by one
  2. If different characters appear in the subsequent comparison process one by one, str1 needs to return to the last position where the character comparison just started before for comparison, and str2 needs to return to the first character
  3. If the character pointed to by str2 is \ 0 in the subsequent comparison one by one, it means that the string str2 is found in str1, and the first character of str2 corresponding to the address of str1 is returned
  4. In addition, after traversal, the character pointed to by str1 is \ 0 (when the character pointed to by str2 is not \ 0), which means that the string str2 cannot be found in str1, and NULL is returned
char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	if (*str2 == '\0')
		return (char*)str1;//If str2 points to an object such as char ch [] = ""; (that is, the content is' \ 0 '), str1 is returned directly
	const char* s1;
	const char* s2;
	const char* p = str1;
//If the content of the object pointed to by str1 is not '\ 0', it will enter the loop
	while (*p)
	{
//Enter the cycle to adjust s2 and s1 positions
		s1 = p;
		s2 = str2;
//The same is traversed
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
//When s2 traverses to the end character, it is found, and the starting address is returned
		if (*s2 == '\0')
		{
			return (char*)p;
		}
//(the above conditions are not satisfied) if '\ 0' is found in s1, it means that the start position p has reached the end character, so it has not been found
		if (*s1 == '\0')
		{
			return NULL;
		}
//If this search is not found, the start position p points to the next position
		p++;
	}
	return NULL;
}

strtok (string slicing function)

  • definition:
char *strtok( char *str//Segmented objects, 
const char *sep//Separator set);
  • be careful:
  1. The first parameter specifies a string that contains 0 or more tags separated by one or more separators in the sep string
  2. The strtok function finds the first delimiter in str, replaces it with '\ 0', and returns the address of the first element of the string before the delimiter
  3. The first parameter of strtok function is not NULL. The function will find the first separator in strToken, and strtok function will remember the position of the next character after the separator
  4. The first parameter of strtok function is NULL. The function will start at the memorized position in the same string and find the next separator
  5. If there are no more tags in the string, a NULL pointer is returned
  • Function demonstration:
#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "- This, a sample string.";
	char* pch;
	pch = strtok(str, " ,.-");
	while (pch != NULL)
	{
		printf("%s\t", pch);
		pch = strtok(NULL, " ,.-");
	}
	return 0;
}
//Output result: this a sample string
#include <stdio.h>
#include <string.h>
int main()
{
	char* p = "abcde@163.com";
	const char* sep = ".@";
	char arr[30];
	char* str = NULL;
	strcpy(arr, p);//Copy the data and process the contents of the arr array
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\t", str);
	}
}
//Output result: ABCDE 163 com
  • Simulation Implementation:
char* strtok (char* str, const char* delim)
{
	// Generate replacement character table
	char table[256] = {0};
    while (*delim != '\0')
    {
        table[*delim] = 1;
        delim++;
    }
	// Use a static pointer to save the string address of the last function call
	static char* pstr = NULL;
	if (str != NULL)
	{
		pstr = str;
	}
	// Ensure that pstr points to a substring that starts with a non replacement character
	while (*pstr != '\0' && table[*pstr] == 1)
	{
		pstr++;
	}	
	// ret saves the first address of the returned substring
	char* rst = (*pstr != '\0') ? pstr : NULL;

	while (*pstr != '\0')
	{
        if (table[*pstr] == 1)
        {
            // The substring is obtained by cutting, and pstr finally points to the next character of the substring
            *pstr++ = '\0';
            break;
        }
        else
        {
            pstr++;
        }
	}
    
	return rst;
}

StrError (a string function that returns a description of the cause of the error)

  • definition:
char *strerror( int errnum );
  • difference:

strerror: searches the internal array for error numbers   errnum and returns a pointer to the error message string

perror: print + strerror (print directly)

  • Function demonstration:
#include <stdio.h> 
#include <string.h> 
int main() 
{ 
    FILE *stream; 
    if ((stream=fopen("crt_fopen.c", "r")) == NULL) //Open file as read
    { 
        perror("perror says open failed"); 
        printf("strerror says open failed: %s\n", strerror(errno)); 
    }
    else 
    { 
        printf("open succeeded on input file\n"); 
        fclose(stream); 
    } 
    return 0; 
}

Note: open the specified file through fopen() function. If the file fails to be opened, the return value of fopen() function is NULL. In this case, error information can be displayed through perror() function or strerror() function

Introduction to memory functions

  • Differences between memory function and string function:

String function: can only operate on strings

Memory function: it can operate on any data type (operate on the contents stored in the object)

memcpy (memory copy function)

  • definition:
void *memcpy( void *dest, const void *src, size_t count //In bytes);
  • be careful:
  1. The memcpy function copies num bytes of data back from the source location to the destination memory location
  2. This function will not stop when it encounters' \ 0 '
  3. If there is any overlap between source and destination, the copied result is undefined
  • Function demonstration:
#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6 };
	int arr2[5] = { 0 };
	memcpy(arr2, arr1, 16);
	int i = 0;
	int size = sizeof(arr2) / sizeof(arr2[0]);
	for (i = 0; i < size; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}
//Output result: 1 2 3 4 0
  • Simulation Implementation:
void* my_memcpy(void* des, const void* src, size_t n)
{
	assert(des && src);
	void* ret = des;//Record initial position
	while (n--)//Circular copy
	{
		*(char*)des = *(char*)src;
		(char*)des = (char*)des + 1;
		(char*)src = (char*)src + 1;
	}
	return ret;
}

memmove (memory move function)

  • definition:
void *memmove( void *dest, const void *src, size_t count );

Note: compared with the memcpy function, the memmove function can copy duplicate addresses (if there is any overlap between source and destination, the desired result can be achieved)

  • Function demonstration:
#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6 };
	int arr2[3] = { 0 };
	memmove(arr1 + 2, arr1, 16);
	int i = 0;
	int size = sizeof(arr1) / sizeof(arr1[0]);
	for (i = 0; i < size; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}
//Output result: 1 2 1 2 3 4
  • Simulation Implementation:
void* my_memmove(void* des, const void* src, size_t n)
{
	assert(des && src);
	void* ret = des;
	if (des < src)
	{
		//If the destination is in front of the source, copy from front to back
		while (n--)
		{
			*(char*)des = *(char*)src;
			(char*)des = (char*)des + 1;
			(char*)src = (char*)src + 1;
		}
	}
	else
	{
		//If the target is behind the source, copy from back to front
		while (n--)
		{
			*((char*)des + n) = *((char*)src + n);
		}
	}
	return des;
}

memcmp (memory comparison function)

  • definition:
int memcmp( const void *buf1, const void *buf2, size_t count );

Note: compare num bytes starting from ptr1 and ptr2 pointers

  • Function demonstration:
#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,6 };
	printf("%d ", memcmp(arr1, arr2, 16));
	return 0;
}
//Output result: 0
  • Simulation Implementation:
int my_memcmp(const void* src1, const void* src2, size_t n)
{
	assert(src1 && src2);

	while (--n)
	{
//Exit directly in case of different
		if (*(char*)src1 != *(char*)src2)
		{
			break;
		}
		(char*)src1 = (char*)src1 + 1;
		(char*)src2 = (char*)src2 + 1;
	}
	return *(char*)src1 - *(char*)src2;
}

Tags: C string

Posted on Tue, 21 Sep 2021 03:42:33 -0400 by spaggle