[c language] recognize string character function + memory function | simulation implementation | strlen strcpy strcat strcmp strstr strtok memcpy memmove memset memcmp

Posted by yorktown on Sat, 22 Jan 2022 19:49:06 +0100

Introduction to character function + memory function

a key

  • Find string length

    • strlen
  • String function with unlimited length

    • strcpy,strcat,strcmp
  • Introduction to string functions with limited length

    • strncpy,strncat,strncmp
  • String lookup

    • strstr,strtok
  • Error message report

    • strerror
  • Memory operation function

    • memcpy,memmove,memset,memcmp

Function introduction

strlen : returns the length of the string str.

size_t strlen ( const char * str );
  • The length of the string is determined by the terminating null character '\ 0': the length of the string is equal to the number of characters between the beginning of the string and '\ 0' = = (excluding '\ 0' itself) = =.
  • It cannot be confused with sizeof function, such as char mystr[100]="test string";, sizeof(mystr) is calculated as 100 and strlen(mystr) is calculated as 11.
  • Note: the string pointed to by str must end with '\ 0', and the return type is size_t is an unsigned integer
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[] = "abcdef";
	char str2[] = "abc";
	if (strlen(str2) - strlen(str1) > 0)
		printf("str1<str2\n");
	else
		printf("str1>str2\n");
	return 0;
}

The result is STR1 < STR2, which is different from expected because the unsigned integer subtraction result is non negative.

strcpy : copy string

char * strcpy ( char * destination, const char * source );
  • Copy the string pointed to by source to the array pointed to by destination, including '\ 0' (and stop at this point).
  • To avoid overflow, the size of the array pointed to by destination should be long enough to contain the same string as source (including '\ 0') and should not overlap source in memory.
  • Return to destination

strcat : connection string

char * strcat ( char * destination, const char * source );
  • Append a copy of the source string to the destination string. In destination = = '\ 0' is overwritten by the first character of source = =, '\ 0' is included at the end of the new string formed by the connection of two strings in destination.
  • destination and source must not overlap.
  • Return to destination
  • Note: the destination string must end with '\ 0'.

strcmp : compare two strings

int strcmp ( const char * str1, const char * str2 );
  • This function starts by comparing the first character of each string. If they are equal to each other, continue to compare the next pair until the characters are different or reach '\ 0'.
  • Return value:
Return valuemeaning
<0The value of the first mismatched character in ptr1 is less than that in ptr2
0The contents of the two strings are equal
>0The value of the first mismatched character in ptr1 is greater than that in ptr2

(the return values in vs are - 1, 0 and 1 respectively)

strncpystrncatstrncmp

The parameter parts of these functions with n have one more size after the parameters of the corresponding function above_ t num

  • strncpy:
    • Copy num characters from the source string to the destination space.
      If the length of the source string is less than num, after copying the source string, append 0 to num after the destination.
  • strncat:
    • Append the first num characters in the source string plus' \ 0 'to the destination string.
      If the length of the source string is less than num, only the contents before '\ 0' are copied.
  • strncmp:
    • Compare up to num characters of string str1 and string str2.
      This function starts by comparing the first character of each string. If they are equal to each other, continue to compare the next pair until the characters are different, or reach '\ 0', or all num characters are compared.

strstr : find substring

const char * strstr ( const char * str1, const char * str2 );
      char * strstr (       char * str1, const char * str2 );
  • Returns the pointer to the first string in str1 where str2 appears. If str2 is not a substring of str1, it returns a null pointer.
  • The comparison process does not include '\ 0', but will stop here.

example:

int main()
{
    char str[] = "This is a simple string";
    char* pch = strstr(str, "simple");
    if (pch != NULL)
        printf("%s", pch);
    else
        printf("Not a substring");
    return 0;
}

Result: simple string

strtok : split string

char * strtok ( char * str, const char * delimiters );
  • The sep parameter is a string that defines the set of characters used as delimiters
  • The str 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 str parameter is not NULL, the function will find the first tag in str, and the strtok function will save its position in the string.
  • If the str parameter 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.

example:

#include <stdio.h>
#include <string.h>
int main()
{
	const char* p = "/.";
	char arr[] = "csdn.net/CegghnnoR";
	char buf[50] = { 0 };
	strcpy(buf, arr);
	
	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);
	//Start return NULL
	str = strtok(NULL, p);
	printf("%s\n", str);
	return 0;
}

Result: csdn
net
CegghnnoR
(null)

strerror : get error message

char * strerror ( int errnum );
  • Some error messages are specified in c language

  • errnum is the error code and returns a pointer to these error information strings.

    It is equivalent to translating the error code into error information.

example:

int main()
{
	//Open file
	FILE* pf = fopen("test.txt", "r");
	if (NULL == pf)
	{
		//What is the reason for the error
		printf("%s\n", strerror(errno));
		return 0;
	}
	//read file
	//...
	
	//Close file
	fclose(pf);
	pf = NULL;

	return 0;
}

Result: No such file or directory

  • Errno is a global variable provided by C language, which can be used directly and placed in errno H in the file
  • When the library function is used, if an error occurs, the errno variable will be set to the error code generated by this execution of the library function

Character classification & conversion function

Header file: ctype h

functionThe parameter returns true if it meets the following conditions
iscntrlAny control character
isspaceBlank characters: space ',' page feed '\ f', line feed '\ n', carriage return '\ r', tab '\ t' or vertical tab '\ v'
isdigitDecimal digits 0 ~ 9
isxdigitHexadecimal digits, including all decimal digits, lower case letters a ~ F and upper case letters a ~ F
islowerSmall letter a~z
isupperCapital letters A~Z
isalphaLetters a ~ Z or a ~ Z
isalnumLetters or numbers, a~z,A~Z,0~9
ispunctPunctuation mark, any graphic character not belonging to numbers or letters (printable)
isgraphAny graphic character
isprintAny printable character, including graphic characters and white space characters
int tolower ( int c );//Turn lowercase
int toupper ( int c );//Capitalize

memcpy : copy memory block

void * memcpy ( void * destination, const void * source, size_t num );
  • Starting from the position pointed to by source, directly copy the value of num bytes backward to the memory block pointed to by destination.
  • The basic type of the object pointed to by the source pointer and destination pointer is independent of this function; The result is a binary copy of the data.
  • This function does not check for '\ 0' in the source -- it always copies num bytes exactly.
  • To avoid overflow, the array size pointed to by the destination and source parameters should be at least num bytes and should not overlap (memmove can be used for overlap). (memcpy in vs can also copy overlapping memory blocks)
  • Return to destination
  • strcpy is dedicated to copying strings, while memcpy can copy various types of data.

example:

#include <stdio.h>
#include <string.h>
typedef struct stu
{
	char name[10];
	int age;
}stu;

//Copy data from arr1 to arr2
int main()
{
	stu arr1[2] = { {"zhangsan",20},{"lisi",18} };
	stu arr2[10] = { 0 };
	memcpy(arr2, arr1, sizeof(arr1));
	for (int i = 0; i < 2; i++)
	{
		printf("%s %d\n", arr1[i].name, arr1[i].age);
	}
}

memmove : moving memory blocks

  • It has the function of memcpy, and the source memory block and target memory block can overlap.

example:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
    //Copy the last four elements to the memory block starting from arr+2
	memmove(arr + 2, arr, 4 * sizeof(arr[0]));
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

Results: 1 2 1 2 3 4

memcmp : compare two pieces of memory

int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • Compare the two num byte memories pointed to by ptr1 and ptr2 byte by byte.

  • Note: unlike strcmp, the function does not stop comparing when it finds a null character.

  • Return value:

    Return valuemeaning
    <0The value of the first mismatched byte in the two memory blocks in ptr1 is less than that in ptr2
    0The contents of the two memory blocks are the same
    >0The value of the first mismatched byte in the two memory blocks in ptr1 is greater than that in ptr2

example:

#include <stdio.h>
#include <string.h>
int main()
{
	char s1[] = "abcd";
	char s2[] = "abad";
	int n = memcmp(s1, s2, 4);
	if (n < 0)
		printf("s1<s2");
	else if (n == 0)
		printf("s1=s2");
	else
		printf("s1>s2");
	return 0;
}

Results: S1 > S2

memset : populating memory blocks

void * memset ( void * ptr, int value, size_t num );
  • Set the num bytes of the memory block pointed to by ptr to the specified value (interpreted as unsigned characters).
int main()
{
	char s[10] = { 0 };
    //Set the first five characters to 'x'
	memset(s, 'x', 5);
	printf("%s", s);
	return 0;
}

Result: xxxxx

  • It can also be used for initialization of integer arrays

Simulation Implementation

Simulation Implementation of strlen

Method 1: counter

int my_strlen(const char* str)
{
	assert(str);
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

Method 2: recursion

int my_strlen(const char* str)
{
	if (*str == '\0')
		return 0;
	else
		return 1 + my_strlen(str + 1);
}

Method 3: pointer

int my_strlen(char* s)
{
   char* p = s;
   while (*p != '\0')
   	p++;
   return p - s;
}

Simulation Implementation of strcpy

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

Simulation Implementation of strcat

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//Found \ 0 in target space
	while (*dest)
	{
		dest++;
	}
	//Append content to target space
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

Simulation 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++;
	}
	return *str1 - *str2;
}

Simulation Implementation of STR

  • Define three pointer variables cur, s1 and s2
    • If s1 and s2 are equal, they are at the same time++
    • If not equal, cur + +, s1 points to the element pointed to by cur, and s2 points to the starting position
    • Repeat the above steps until s2 points to '\ 0' (found) or cur points to '\ 0' (not found)

char* my_strstr(const char* str, const char* substr)
{
	const char* s1 = str;
	const char* s2 = substr;
	const char* cur = str;
	//The substring is \ 0, and the original string is returned directly
	assert(str && substr);
	if (*substr == '\0')
	{
		return (char*)str;
	}
	while (*cur)
	{
		s1 = cur;
		s2 = substr;
		while (*s1 &&  *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)cur;

		cur++;
	}
	return NULL;
}

Simulation and implementation of memcpy

void* my_memcpy(void* dest, const void*src, size_t num)
{
	void* ret = dest;
	assert(dest && src);

	while (num--) 
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}

	return ret;
}
  • You can receive any type of parameter using void * type
  • When the pointer moves backward, it needs to be cast to char first*

Simulation Implementation of memmove

To realize overlapping space copy, it is necessary to discuss it in two cases:

  • If the red part is copied to the blue part, it should be copied from front to back, 3 - > 1, 4 - > 2, 5 - > 3, 6 - > 4. The result is 3, 4, 6, 6. If it is copied from back to front, it will become 5, 6, 6, 6, because 3 and 4 are covered by 5 and 6 before being copied.
  • If the blue part is copied to the red part, it should be copied from back to front, and the result is 1 2 1 2 3 4. If it is copied from front to back, it will become 1 2 1 2 1 2 2.

Therefore, when the source pointer is larger than the target pointer (the source memory block is after the target memory block), copy from front to back,

If the source pointer is smaller than the target pointer (the source memory block is before the target memory block), it is copied from back to front.

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	
	if (dest < src)
	{
		//Front - > rear
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//Rear - > front
		while (num--)
		{
			*((char*)dest+num) = *((char*)src + num);
		}
	}
	return ret;
}

Topics: C Spring Back-end pointer