[C advanced level] brother Peng takes you to play with · strings and memory functions

Hello, everyone. I'm safe and sound.

catalogue

1, Introduction to common string library functions

1,strlen()

Implementation of strlen by user-defined function simulation

2,strcpy()

Implementation of strcpy by user-defined function simulation

3,strcat()

Implementation of strcat by user-defined function simulation

4,strcmp()

Implementation of strcmp by user-defined function simulation

5,strncpy()

6,strncat()

7,strncmp()

8,strstr()

Implementation of STR by user-defined function simulation

9,strtok()

10,strerror()

2, Character classification function

3, Common memory operation functions

1,memcpy()

Implementation of memcpy by user-defined function simulation

2,memmove()

Implementation of memmove by user-defined function simulation

3,memcmp()

4,memset()

4, Meet Enron meet you, not negative code, not negative Qing.

preface:

I was in a bad state some time ago, so I haven't updated it for 24 days. When I turned on my mobile phone, I didn't reply in time. I'm going back again and again these days. I'm really sorry. Thank you for your support and company. Now I'm starting to catch up slowly and come on together.  

1, Introduction to common string library functions

The operation and processing of characters and strings in C language is very frequent, but C language itself has no string type, so the strings in C language are usually placed in constant strings or character arrays;

String constants apply to string functions that do not modify it.

Key points of this chapter:

Find string length

  • strlen

String library function with unlimited length

  • strcpy
  • strcat
  • strcmp

String library function with limited length

  • strncpy
  • strncat
  • strncmp

String lookup

  • strstr
  • strtok

Error message report

  • strerror

Character operation library function

Memory operation Library

  • memcpy
  • memmove
  • memset
  • memcmp

be careful:

Unlimited length means that it is appended to '\ 0', which has nothing to do with the length;

Limited length means that it is related to length. It may not be easy to understand. Don't worry. You'll understand when you see the back.  

1,strlen()

Function prototype:

Function function:

Find the length of the string

Note: the return value type is size_t. This size_ What exactly is t?

Actually size_t is designed for the return value of sizeof operator, which can be considered as size_t is the well-known unsigned int. because it is for length, it will certainly not be negative. Therefore, unsigned integer is used, but it is also prone to bug s. Please see the following code:

Interpret the following code. What is the output result

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

int main()
{
	if (strlen("abc") - strlen("abcdef") > 0)
		printf(">");
	else
		printf("<=");
	return 0;
}

Yes, the answer is to output ">", why? 3 - 6 = - 3 duck, what's going on?

This is because the return value of strlen is size_t. It's an unsigned number, so if you subtract two unsigned numbers, the answer must be an unsigned number. If you still don't understand, you can see this article and it's very clear.

Deep analysis of data storage in memoryhttps://bit-runout.blog.csdn.net/article/details/121576136 How to modify it?

Scheme 1: forced type conversion

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

int main()
{
	if ((int)strlen("abc") - (int)strlen("abcdef") > 0 )
		printf(">");
	else
		printf("<=");
	return 0;
}

Scheme 2: direct comparison

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

int main()
{
	if (strlen("abc") > strlen("abcdef"))
		printf(">");
	else
		printf("<=");
	return 0;
}

be careful:

  • The string ends with '\ 0'. strlen returns the number of characters before '\ 0' in the string (excluding '\ 0');
  • The string pointed to in the parameter must end with '\ 0';
  • Note that the return value of the strlen function is size_t type, which belongs to unsigned type (especially error prone)

Code example:

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

int main()
{
    int len = strlen("abcdef");
	printf("%d\n", len);

	return 0;
}

Implementation of strlen by user-defined function simulation

[take you to brush LeetCode with your hands] - 18 The user-defined function implements the strlen() function (job)_ Safe blog - CSDN blog today is the 18th day of Li Kou punch in! This question is not the above question, but an assignment. Brother Peng said it was very important, so I sorted it into a small blog post. Original title: the custom function realizes the strlen() function. First, let's feel the strlen() function: #include < stdio h>#include<string. h> Int main() {char arr [] = "abcdefghij"; printf ("% d \ n", strlen (ARR)); / / output 10return 0;}strlen().https://bit-runout.blog.csdn.net/article/details/121381957 method:

  1. Counter method
  2. Recursive method
  3. Pointer pointer

Method 1: counter method

int my_strlen(const char* str)
{
	assert(str);//Assertion str is not null
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

Method 2: recursive method

int my_strlen(const char* str)
{
	assert(str);//Assertion str is not null
	//Find boundary
	if (*str == '\0')
	{
		return 0;
	}
	int count = my_strlen(str + 1);
	//Note that str + + and str+1 are different concepts
	count++;
	return count;
}

It should be noted here that str + + and str+1 are not the same concept. str + + is used first and then + +. This problem can be written in the form of + + str and used first and then + +.

Method 3: pointer pointer

Pointer - pointer actually represents the number of elements between two pointers. Note that there are not a few bytes in the middle.

int my_strlen(const char* str)
{
	assert(str);
	const char* cur = str;
	while (*cur != '\0')
	{
		cur++;
	}
	return cur - str;
}

2,strcpy()

Function prototype:

Function function:

Copy the source string to the target string and return the address of the first element of the target string.  

Interpret the following codes:

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

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

	return 0;
}

This problem is to copy the string arr2 # to the string arr1, and return the address of the first element of arrr2 (the address of the first element of the target string). Therefore, the output of the above code is abcdef. The question here is whether the '\ 0' in the string arr1 will be copied to the string arr2. Therefore, the following code is used to verify this problem:

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

int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = "XXXXXXXXXX";
	printf("%s\n", strcpy(arr2, arr1));

	return 0;
}

First, when the string arr1 ¢ has not been copied to arr2 ¢ yet, the data they store is as follows:

After strcpy(arr2, arr1) is executed, the data stored in arr2 is as follows:

It can be seen that when copying the string arr1 (source string) to the string arr2 (target string), the '\ 0' at the end of the source string will be automatically copied, and the address of the starting position of the target string will be returned.

Another problem here is: if '\ 0' is not added at the end of the source string (this is demonstrated in the form of character array, and '\ 0' will be automatically filled at the end of the normal string), please see the following code:

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

int main()
{
	char arr1[] = { 'a','b','c','d','e','f' };
	char arr2[20] = "XXXXXXXXXX";
	
	printf("%s\n", strcpy(arr2, arr1));
	return 0;
}

Code execution result:

Therefore, it should be noted that if you want to copy the source string to the target string, you must ensure that the source string contains' \ 0 ', otherwise the copy will fail.  

Therefore, you should pay attention to the following points when using strcpy to copy strings:

  • The source string must end with '\ 0';
  • When copying, the '\ 0' in the source string will be copied to the target string together;
  • The target string (target space) must be large enough to store the source string;
  • Another point is that the target string must be changeable

See the following code:

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

int main()
{
	char arr1[] = "abcdef";
	const char* p = "XXXXXXXXXX";
	printf("%s\n", strcpy(p, arr1));
	return 0;
}

The execution of the program is wrong, because the target string at this time is modified by const and cannot be modified.  

Implementation of strcpy by user-defined function simulation

[hand in hand to help you brush the questions] - 22 Interview question: Simulated Implementation of strcpy library function (non force deduction)_ Safe blog - CSDN blog [preface] today is the 22nd day of punching in and out! This is a good topic. There are some good coding skills in it. You should pay attention to it. Original title: simulate the implementation of strcpy library function, OK, no more nonsense, directly on the code Primary code: out of 10 points --- 5 points #include < stdio h>void my_ strcpy(char* dest, char* src){while (*src != '\0'){*dest = *src;dest++;src++;}* dest =https://bit-runout.blog.csdn.net/article/details/121457507 Code execution:

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

3,strcat()

Function prototype:

Function function:

Append the source string to the destination string and return the address of the first character of the destination string

Interpret the following codes:

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

int main()
{
	char arr1[30] = "hello";
	char arr2[] = "world";

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

The above code splices "world" after "hello", so the print results are as follows:

In fact, the precautions for using strcat library function are very similar to strcpy. I won't explain it again here:

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

So imagine: if we let ourselves implement the strcat function, what should we do? First think about the general idea. First, we need to find the end flag '\ 0' of the target string, then splice the source string behind the target string, and finally return the address of the first character of the target string. It seems very simple. Let's implement it:

Implementation of strcat by user-defined function simulation

Code execution:

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest && src);
	//1. Found target string \ 0
	while (*dest)//Note that it is wrong to write the loop condition as * dest + +, because \ 0 will be skipped. Please review it carefully
	{
		dest++;
	}
	//2. Copy source string
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

4,strcmp()

Function prototype:

Function function:

Compare the dictionary order of the characters in the corresponding position

Standard provisions:

  • If the first string > the second string, a number greater than 0 will be returned;
  • If the first string = = the second string, 0 is returned;
  • If the first string < the second string, a number less than 0 is returned.

Knock on the blackboard:

The two strings cannot be compared directly, nor can they be added or subtracted directly, because the string represents the address of the first character. In other words, if you compare directly, the comparison is not the content of the string, but the address, so it is wrong.  

Implementation of strcmp by user-defined function simulation

Code execution:

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)//Notice that it is to judge the equality in the loop body, and think about why
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (*str1 > *str2)//return *str1 - *str2;
		return 1;
	else
		return -1;
}

5,strncpy()

Function prototype:

Look at the following code:

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

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

Such functions are relatively safer, more controllable and more flexible.  

6,strncat()

Function prototype:

Look at a piece of code:

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

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

 

From the above, we can see that '\ 0' will be automatically filled after appending, and it will be appended to the end of the first '\ 0' in the target string.

7,strncmp()

Function prototype:

Look at the following code:

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

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

Note: the above code compares the first three characters of the string, not the third character.

8,strstr()

Function prototype:

Return value:

Function function:

Find string

Take a look at the following code:

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

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

	char* ret = strstr(arr1, arr2);

	if (NULL == ret)
		printf("Can't find\n");
	else
		printf("%s\n", ret);
	return 0;
}

 

Implementation of STR by user-defined function simulation

Code execution:

char* my_strstr(const char* str, const char* substr)
{
	const char* s1 = str;
	const char* s2 = substr;
	const char* cur = str;

	assert(str && substr);
	//exceptional case
	if (*substr == '\0')
		return (char*)str;
	while (*cur)
	{
		s1 = cur;
		s2 = substr;
		while (*s1 && *s2 && *s1 == *s2)//Attention * S1! =\ 0&&*s2!='\ 0
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return (char*)cur;
		cur++;
	}
	return NULL;
}

9,strtok()

Function prototype:

Precautions before use:

  • The sep parameter is a string that defines the set of characters used as separators;
  • The first parameter specifies a string, which 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: strtok function will change the operated string, so the string segmented by strtok function is generally the content of temporary copy and can be modified);
  • When the first parameter of strtok function is not NULL, the function will find the first tag in str, and strtok function will save its position in the string;
  • When the first parameter of strtok function is NULL, the function will start at the saved position in the same string to find the next tag;
  • A NULL pointer is returned if there are no more tags in the string

It can also be said that:

  • When the strtok function finds the first tag, the first parameter of the function is not NULL;
  • When the strtok function finds a non first tag, the first parameter of the function is NULL

Look at the following code:

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

int main()
{
	const char* p = "@.";
	char arr[] = "zpengwei@yeah.net";
	char buf[50] = { 0 };//As a temporary copy
	strcpy(buf, arr);
	char* str = strtok(buf, p);
	printf("%s\n", str);//zpengwei
	str = strtok(NULL, p);
	printf("%s\n", str);//yeah
	str = strtok(NULL, p);
	printf("%s\n", str);//net
	return 0;
}

However, it seems too cumbersome to use in this way. Take a look at the following improved code:

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

int main()
{
	const char* p = "@.";
	char arr[] = "zpengwei@yeah.net";
	char buf[50] = { 0 };//As a temporary copy
	strcpy(buf, arr);
	char* str = NULL;
	for (str = strtok(buf, p); str != NULL; str = strtok(NULL, p))
	{
		printf("%s\n", str);
	}
	//char* str = strtok(buf, p);
	//printf("%s\n", str);//zpengwei
	//str = strtok(NULL, p);
	//printf("%s\n", str);//yeah
	//str = strtok(NULL, p);
	//printf("%s\n", str);//net
	return 0;
}

10,strerror()

Function prototype:

Return value:

Function function:

Returns the error information corresponding to the error code

Look at the following code:

//C language can operate files
//Open file - fopen

//When the library function is used, if an error occurs, the global error variable errno will be set as the error code generated by this execution of the library function
//Errno is a global variable provided by C language, which can be used directly and placed in errno H in the document
#include<stdio.h>
#include<errno.h>
#include<string.h>
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;
}

Common string library functions are finally explained. Change your mood.

2, Character classification function

When using character manipulation functions, it should be noted that the header file is ctype h

The function is not introduced in detail.

Character conversion:

  • int tolower(int c)
  • int toupper(int c)

Code example:

#include<stdio.h>
#include<ctype.h>

int main()
{
	char ch = 0;
	ch = getchar();
	if (islower(ch))
		ch = toupper(ch);
	else
		ch = tolower(ch);

	printf("%c\n", ch);

	return 0;
}

3, Common memory operation functions

1,memcpy()

Function prototype:

Note that the third parameter in the memory operation function is in bytes.

Think about why it's a void * type?

Because the designer doesn't know what type the library function will be used to copy when designing the library function, it is best to design it as void *.  

Look at the following code:

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

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

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

Implementation of memcpy by user-defined function simulation

Code execution:

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;//Note that the return type is void *, not void,
	assert(dest && src);
	while (num--)//Use first, then--
	{
		*(char*)dest = *(char*)src;//Think about why cast type to char *, because only it is most appropriate
		dest = (char*)dest + 1;//Note that direct dest++,src + + is wrong because it is an empty type
		src = (char*)src + 1;
	}
	return ret;
}

2,memmove()

Function prototype:

In fact, C language only requires:

Memcpy can copy non overlapping memory space. Memmove handles those overlapping memory copies. That is, if the function of memcpy is A, the function of memmove is A+B

So what is overlapping memory copies? Please see the following code:

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

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	
	memmove(arr1 + 2, arr1, 5 * sizeof(arr1[0]));//Overlapping memory copies occur when processing the same space

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

Implementation of memmove by user-defined function simulation

Code execution:

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)//Copy back
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else//Copy back to front
	{
		//src = (char*)src + num - 1;// Be sure to - 1
		//dest = (char*)dest + num - 1;
		//while (num--)
		//{
		//	*(char*)dest = *(char*)src;
		//	dest = (char*)dest - 1;
		//	src = (char*)src - 1;
		//}
		while (num--)//First use, then --, in the loop body is the num after -- (really wonderful)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}

3,memcmp()

Function prototype:

Return value:

It's relatively simple. Take a look at the following code:

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

int main()
{
	int arr1[] = { 1,2,7,4,5 };
	int arr2[] = { 1,2,3,4,5 };
	int ret = memcmp(arr1, arr2, 9);

	printf("%d\n", ret);
	return 0;
}

4,memset()

Function prototype:

Function parameters:

Function function:

Set memory in bytes

Look at the following code:

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

int main()
{
	char arr[20] = { 0 };
	memset(arr, 'x', 10);
	printf("%s\n", arr);
	return 0;
}

 

You can also operate on integers, but because it is an operation on memory, you should consider the byte order of the size end. If you forget what the size end is, you can see this article:

[hand in hand to help you brush the questions] - 27 Judgment of byte order at large and small ends (non force deduction, baidu written test questions)_ CSDN blog [preface] today is the 27th day of punching in and out! Thank you for your company. Your recognition is my biggest motivation. Hold your fist!! Take a look at the following code: #include < stdio h>int main(){int a = 0x11223344;return 0;} The order of storage in memory is wrong. Why? Here we will introduce the size end. What is big end and small end? Large end byte order storage: when the low order of a data is placed at the high address, the high order of the data is placed at the low address; Small end byte order storage: when the low order of a data is placed at the low address, the number ishttps://bit-runout.blog.csdn.net/article/details/121583724

4, Meet Enron meet you, not negative code, not negative Qing.

Ten thousand character blog posts are not easy to be original.

Ask for a triple

Keywords: C

Added by poison on Mon, 14 Feb 2022 02:06:07 +0200