A blog series (1) - the use and precautions of all string functions and memory functions in C language

Table of contents

1. Find the string length function

1.1、strlen

2. String copy (cpy), splicing (cat), comparison (cmp) functions

2.1. String functions with unlimited length

2.1.1、strcpy

2.1.2、broken

2.1.3、strcmp

2.2. String functions with limited length

2.2.1、strncpy

2.2.2、strncat

2.2.3、strncmp

3. String search function

3.1、strstr

3.2、strtok

4. Error message reporting function

4.1、Strerror

4.2、perror

5. Character functions

5.1. Character classification function

5.2. Character conversion function

5.2.1、tolower

5.2.2、toupper

6. Memory operation function

6.1、memcpy

6.2、memmove

6.3、memset

6.4、memcmp

1. Find the string length function

1.1、strlen

  • strlen is used to find the length of a string.
  • Include header file <string.h>.
  • The string has '\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' .

Notice:

1. The return value of the function is size_t, which is unsigned ( error-prone)

2. Because strlen returns the number of characters before '\0', if there is a '\0' in the middle of the string, the returned value will return the number of characters before '\0' in the string.

For example: "abc \0 def" this string, using the strlen function will return 3.

【How to use】 

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

【operation result】

[Error-prone reminder]

请问ret的值是多少?
int ret = strlen("abc") - strlen("abcdef");

The answer is 3, because the return value of the function is size_t, which is an unsigned integer.

[Simulating implementation of strlen]

int my_strlen(char* arr)
{
	int count = 0;
	while (*arr != '\0')
	{
		count++;
		arr++;
	}
	return count;
}

int main()
{
	char arr[] = "Hello hacynn";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

2. String copy (cpy), splicing (cat), comparison (cmp) functions

2.1. String functions with unlimited length

2.1.1、strcpy

  • strcpy is used to copy strings, copy string 2 to string 1.
  • Include header file <string.h>.
  • The source string must end with '\0'.
  • '\0' in the source string will be copied to the target space.
  • The target space must be large enough to accommodate the source string.
  • The target space must be variable.

【Instructions】 

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

【operation result】 

[Simulating implementation of strcpy]

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

int main()
{
	char arr1[] = "Hello hacynn";
	char arr2[20] = { 0 };
	my_strcpy(arr2,arr1);
	printf("%s\n", arr2);
	return 0;
}

2.1.2、broken

  •  strcat is used to splice two strings, splicing string 2 to the end of string 1.
  • Include header file <string.h>.
  • The source string must end with '\0' (to ensure that the end of the target space is found), and the '\0' of the source string will also be copied during copying.
  • The target space must be large enough to accommodate the contents of the source string and be able to be modified.

Notice:

        The string cannot append itself, because when appending itself, the '\0' of the target string will be overwritten during the appending process, and because the target string is the source string at this time, the source character will be Without '\0', splicing will continue leading to an infinite loop.

        Although this function can splice itself in some environments, the C language standard does not stipulate that strcat can splice itself, so it is best not to use this function when splicing itself. If you really need to add your own scene, it is recommended to use the strncat function . This function will be explained below.

【How to use】

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

 【operation result】

[Simulating the implementation of strcat]

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
    //找到目标空间的末尾
	while (*dest != '\0')
	{
		dest++;
	}
    //数据追加
	while (*dest = *src)
	{
		dest++;
		src++;
	}
	return ret;
}

int main()
{
	char arr1[20] = "Hello ";
	char arr2[] = "hacynn" ;
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

2.1.3、strcmp

  • strcmp is used to compare two strings.
  • Include header file <string.h>.
  • Misunderstanding: This function does not compare the length of strings, but compares the size of characters at corresponding positions (ASCII).
  • 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

【How to use】

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abz";
	if (strcmp(arr1, arr2) > 0)
		printf(">\n");
	else if (strcmp(arr1,arr2) < 0)
		printf("<\n");	
    else
        printf("=\n");
	return 0;
}

【operation result】 

[Simulating implementation of strcmp]

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

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abz";
	if (my_strcmp(arr1, arr2) > 0)
		printf(">\n");
	else
		printf("<=\n");	
	return 0;
}

2.2. String functions with limited length

  • It is a string function that can limit the number of operations.
  • Include header file <string.h>.

2.2.1、strncpy

  • The only difference from strcpy is one parameter, which records the number of operations to be performed. 
  • 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 the end of the target until num.
  • Because the number of copies is determined by the user, there is a possibility that \0 has not been copied.

【How to use】 

int main()
{
	char arr1[] = "Hello hacynn";
	char arr2[20] = { 0 };
	strncpy(arr2, arr1, 5); //拷贝前五个字符 ,此时拷贝\0后arr2中并不会有\0
	printf("%s\n", arr2);
	return 0;
}

【operation result】

【Special cases】

If the length of the source string is less than num , after copying the source string, append 0 to the end of the target until num. as follows:

int main()
{
	char arr1[] = "Hello";
	char arr2[20] = "xxxxxxxxxxxxxxxxx";
	strncpy(arr2, arr1, 10);   //此时10大于arr1的元素个数,就会在后添加0直至够10个
	printf("%s\n", arr2);
	return 0;
}

2.2.2、strncat

  • The difference is only one parameter with strcat, which records the number of operations to be performed.
  • Use strncat to append. When the appending ends, even if it does not reach \0, a \0 will be appended at the end.
  • If the length of the source string is less than num , appending will automatically stop after appending the source string. Note the difference here with strncpy.
  • Include header file <string.h>.

【How to use】

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

【operation result】 

2.2.3、strncmp

  • The only difference from strcmp is one parameter, which records the number of operations to be performed.
  • Include header file <string.h>.

【How to use】

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcz";
	if (strncmp(arr1, arr2, 3) > 0)   //只比较前三个字符
		printf(">\n");
	else if (strncmp(arr1, arr2, 3) == 0)
		printf("=\n");
	else
		printf("<\n");
	return 0;
}

【operation result】

 

3. String search function

3.1、strstr

  • Find whether a string exists in another string, that is, find a substring .
  • Returns a pointer to the first occurrence of str2 in str1 , or a null pointer NULL if str2 is not part of str1.
  • Include header file <string.h>.

【How to use】

It can be seen that even if there are two strings, only the address that appears first will be returned.

int main()
{
	char arr1[] = "abcdefghidef";   //def出现了两次
	char arr2[] = "def";
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
		printf("找不到\n");
	else
		printf("%s\n", ret);
	return 0;
}

【operation result】 

[Simulating implementation of strstr]

const char* my_strstr(const char* str1, const char* str2)
{
    if (*str2 == '\0')
		return str1;
	char* pc = str1;  //pc用于记录开始匹配的位置
	while (*pc)
	{
		char* s1 = pc;   //遍历str1指向的字符串
		char* s2 = str2; //遍历str2指向的字符串
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return pc;
		pc++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "abcdefghidef";
	char arr2[] = "def";
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
		printf("找不到\n");
	else
		printf("%s\n", ret);
	return 0;
}

[Illustration] 

3.2、strtok

 

A rather strange function 
char * strtok (char * str, const char * delimiters);
  • String cutting function, such as [email protected], when the cutting marks are @ and ., three strings can be cut through three reasonable uses: hacynn nash com
  • Include header file <string.h>.
  • The delimiters parameter is a string that defines the set of characters used as delimiters .
  • The first parameter specifies a string containing zero or more tokens separated by one or more delimiters in the delimiters 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.
  • If no more tokens exist in the string, a NULL pointer is returned

【How to use】

int main()
{
	char arr[] = "[email protected]";
	char buf[200] = { 0 }; //因为strtok会改变被操作字符串,
	                        //所以拷贝一个临时变量来操作
	strcpy(buf, arr);
	char* p = "@.";
	char* s = strtok(buf, p); //参数不为NULL,找到第一个标记
	printf("%s\n", s);

	s = strtok(NULL, p); //参数为NULL,找到下一个标记
	printf("%s\n", s);

	s = strtok(NULL, p); 参数为NULL,找到下一个标记
	printf("%s\n", s);

	return 0;

【operation result】

[Usage optimization]

In actual development, we don't necessarily know what the string looks like. How many times does this string need to be cut? Therefore, it is not advisable to manually set the number of cuts and hard-code the code. Instead, the following method should be used for automatic cutting . .

int main()
{
	char arr[] = "[email protected]@abcd";
	char buf[200] = { 0 };
	strcpy(buf, arr);
	char* p = "@.";

	char* s = NULL;
	for (s = strtok(buf, p); s != NULL; s = strtok(NULL, p))
	{
		printf("%s\n", s);
	}
	

	return 0;
}

This cleverly uses the feature that the initialization part of the for function is only executed once, and strtok only needs to pass the address for the first time, and only needs to pass NULL at other times.

[Optimization results after optimization] 

4. Error message reporting function

4.1、Strerror

  • The strerror function translates the error code into error information and returns the starting address of the string of the error information.
  • Include header file <string.h>.
  • When using library functions in C language, if an error occurs, the error code will be placed in the errno variable. errno is a global variable and can be used directly.

 [Error code example]

int main()
{
	int i = 0;
	for ( i = 0; i < 10; i++)
	{
		printf("%d: %s\n", i, strerror(i));
	}
	return 0;
}

Each error code corresponds to an error message 

【How to use】

Taking opening a file as an example, fopen opens the file in the form of reading. When the file exists, the opening is successful. When the file does not exist, the opening fails and returns a null pointer. You can use this to set an error message when opening fails.

int main()
{
	FILE* pf = fopen("add.txt", "r");  //当前文件路径中并没有add.txt文件,打开失败
	if (pf == NULL)
	{
		printf("打开文件失败,原因是:%s\n", strerror(errno));
		return 1;
	}
	else
	{
		printf("打开文件成功\n");
	}
	return 0;
}

【operation result】

4.2、perror

  • perror is also used to translate error messages, but unlike strerror, perror will directly print the error message corresponding to the error code. The string parameter passed in perror is the part of the customized display information , and the printed result is  the customized display information: error message
  • Include header file <stdlib.h>
  • It can be simply understood as: perror = printf + strerror, which means translation and printing.

【How to use】

int main()
{
	FILE* pf = fopen("add.txt", "r");
	if (pf == NULL)
	{
		perror("打开文件失败");   //注意:此处是perror,不是printf。
		return 1;
	}
	else
	{
		printf("打开文件成功\n");
	}
	return 0;
}

【operation result】 

5. Character functions

5.1. Character classification function

The character classification function is very simple to use . Due to limited space, I will not list them one by one here. You only need to understand the picture below.

5.2. Character conversion function

5.2.1、tolower

As you can tell from the name, this function is used to convert uppercase letters into lowercase letters. The only thing you need to pay attention to with this type of function is that the function has a return value, and the return type is int . Therefore, it is best to use an int ret to receive the return value when using it. .

int main()
{
	int ret = tolower('A');
	printf("%c\n", ret);
}

5.2.2、toupper

Convert lowercase letters to uppercase letters. Other attention points are consistent with tolower.

6. Memory operation function

The string functions mentioned above only apply to strings , but the data in memory is not only characters, which leads to great limitations of these functions. Therefore, there is a need for a function that can be applied to all types of data, which is why the memory operation function appears. Let's learn about memory operation functions.

6.1、memcpy

  • The function memcpy copies num bytes of data starting from the source location to the destination memory location.
  • Include header file <string.h>
  • This function does not stop when it encounters '\0'.
  • If there is any overlap between source and destination, the results of copying are undefined .
  • Because the C language standard does not stipulate that memcpy can be applied to the copy of overlapping memory, so memcpy is used for copying non-overlapping memory, and the memmove function explained next is used for copying overlapping memory .

【How to use】 

Use memcpy to copy integer data.

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

【operation result】 

 

[Simulating implementation of memcpy]

void* my_memcpy(void* dest, const void* src, size_t sz)
{
	void* ret = dest;
	while (sz)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
		sz--;
	}
	return ret;
}

int main()
{
	int arr1[10] = { 0 };
	int arr2[] = { 1,2,3,4,5 };
	my_memcpy(arr1, arr2, sizeof(int) * 5);
	int i = 0;
	for ( i = 0; i < 5; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

6.2、memmove

  •  The parameters and functions of memmove are exactly the same as memcpy.
  • Include header file <string.h>
  • The only difference is that the source memory block and target memory block processed by the memmove function can overlap .
  • Therefore, when an overlapping memory copy occurs, the memmove function is used to handle it.

 [Simulating implementation of memmove]

void* my_memmove(void* dest, const void* src, size_t sz)
{
	void* ret = dest;
	if (dest < src)
	{
		while (sz)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
			sz--;
		}
	}
	else
	{
		while (sz--)
		{
			*((char*)dest + sz) = *((char*)dest + sz);
		}
	}
	return ret;
}

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

6.3、memset

  • Set the first num bytes of the space pointed to by ptr to the specified value value.
  • Include header file <string.h>

【How to use】 

int main()
{
	char arr[] = "hello world";
	memset(arr + 6, 'x', 3);
	printf("%s\n", arr);
	return 0;
}

 【operation result】

6.4、memcmp

  • Compare the contents of the first num bytes of ptr1 and ptr2.
  • Include header file <string.h>
  • The standard stipulates: If
    ptr1 is greater than ptr2, a number greater than 0 is returned.
    If ptr1 is equal to ptr2, 0 is returned.
    If ptr1 is less than ptr2, a number less than 0 is returned.

 【How to use】

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

【operation result】 


If you think the author's writing is good, please give the blogger a big like and support. Your support is my biggest motivation for updating!

If you think the author's writing is good, please give the blogger a big like and support. Your support is my biggest motivation for updating!

If you think the author's writing is good, please give the blogger a big like and support. Your support is my biggest motivation for updating!

Guess you like

Origin blog.csdn.net/zzzzzhxxx/article/details/133243791