Commonly used string functions in C language - what exactly is in the header file <string.h>?

1. strlen - find the length of a string

1.1 Declaration and Use of strlen

strlen, if we have some basic English, it is not difficult to know what this function is used for literally, str means string, and len means length, which means length. That is, strlen is a function that finds the length of a string . We use the cplusplus website to observe the function declaration of strlen and the meaning of each parameter.

We can know that the length of the string required by strlen is the number of characters before the end of the string . That is, we assume that there is a string "hello world", then the required length of the string is the number of all characters before '\0', which is 11. Then the length of this string is returned by the return value , so we must define a variable to receive the return value if we want to know what the length of the string is . Then the parameter part is of course the first address of the string .

1.2 Usage of strlen

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

int main()
{
	char str1[] = "hello world";
	char* str2 = "hello world";

	int len1 = strlen(str1);//数组名表首元素地址
	int len2 = strlen(str2);//str2 指针变量存放的也是首元素地址

	printf("%d\n", len1);
	printf("%d\n", len2);

	//这种写法也可以输出长度
	//printf("%d\n", strlen(str1));
	//printf("%d\n", strlen(str2));

	return 0;
}

One thing to note is that the return value of strlen is of type size_t , which is an unsigned integer. Its meaning is that it is impossible to find negative numbers when finding the length, so the memory is optimized to a certain extent (using signed integers will waste the space used to store negative numbers).

 1.3 Simulation implementation of strlen

We have analyzed the principle of strlen above, so now we use what we have learned to " create " a strlen function of our own.

#include <stdio.h>
#include <assert.h>
unsigned int my_strlen(const char* str)//我们不改变字符串的内容,所以用 const 来进行修饰
{
	assert(str);//避免是一个空指针
	unsigned int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
	char str1[] = "hello world";
	char* str2 = "hello world";

	int ret1 = my_strlen(str1);
	int ret2 = my_strlen(str2);

	printf("%d\n", ret1);
	printf("%d\n", ret2);

	return 0;
}

2. strcpy - string copy

2.1 Declaration and Use of strcpy

We understand its literal translation, str table string, that is, string, cpy table copy, that is, copy. That is, the strcpy function is used to copy strings . Then we use the cplusplus website to observe the declaration of strcpy and the meaning of each parameter.

 

We can translate it to know the function of strcpy, copy the string pointed to by the source pointer to the array pointed to by the destination pointer, and the copied content contains the string terminator . And the array pointed to by the destination pointer must have enough space to hold the contents after the copy. 

From this we know that strcpy requires two parameters , one is an array and the other is a string. And the space of the array must be large enough. The return value is the address before the returned array was copied . The meaning of this is to prevent the loss of the content before the copy.

2.2 Usage of strcpy

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

int main()
{
	char dest[20] = "row your boat";
	char src[] = "hello world";
	strcpy(dest, src);
	printf("%s\n", dest);
	return 0;
}

This is the most common usage of strcpy, we just need to remember one thing: the copied content contains '\0' . That is to say, even if the length of the string I copied is not as long as the original string of the array, but I include '\0', from the perspective of the C language, the content after '\0' is not counted from the beginning. the content of the string .

2.3 Simulation implementation of strcpy

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

char* my_strcpy(char* dest, const char* src)//dest 指向的数组空间是要被改变的,但是 src 指向的字符串不需要改变
{
	assert(dest && src);//防止其中某个是无效指针
	char* ret = dest;
	while (*dest++ = *src++)
		;	//注意 while 循环执行了空语句

	return ret;
}
int main()
{
	char dest[30] = "gently down the stream";
	char src[] = "life is but a dream";

	my_strcpy(dest, src);
	printf("%s\n", dest);
	return 0;
}

3. strcmp - string comparison

3.1 Declaration and Use of strcmp

The same is true, we can roughly understand what this function is used for through literal translation. str table string, that is, string, cmp table compare, that is, comparison . We also observe the declaration of this function and the meaning of each parameter through the cplusplus website.

We can know the principle of this function by translating it. The principle is: the comparison starts from the first character of the two strings. If the two characters are equal, then the two strings will compare the next pair of characters until the two characters are not equal, and then compare size . Returns an integer less than 0 if the first character is less than the second, 0 if it is equal, and an integer greater than 0 if it is greater .

Both of its arguments are strings to compare. In order to facilitate understanding, we understand it in the form of drawing .

 

 

 3.2 Usage of strcmp

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

int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret = strcmp(str1, str2);
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

 3.3 Simulation implementation of strcmp

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

int my_strcmp(const char* str1, const char* str2)//两个字符串的内容都不需要修改,用 const 修饰
{
	assert(str1 && str2);//防止是无效指针

	while (*str1 == *str2)//如果相等则进入循环
	{
		if (*str1 == '\0')//*str1 == '\0' 了并且进入循环了,说明两个字符串比较完成了,没有不相等的字符
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;//两个字符的差作为返回值
}
int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret = my_strcmp(str1, str2);
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

4. strcat - String Append

4.1 Declaration and Use of strcat

 We use the cplusplus website to observe the declaration of strcat and the meaning of each parameter.

Translate it until the usage of the strcat function: append the string pointed to by the source pointer to the array pointed to by the destination pointer and there is enough space (I tried to append to the string, but failed), and the appended location is the destination pointer points to '\0' of the string, that is, copy from this position . Note that the position of the appended '\0 ' is the position of the first '\0' .

4.2 Usage of strcat 

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

int main()
{
	char str1[50] = "row row row your boat,";
	char* str2 = "gently down the stream";
	strcat(str1, str2);
	printf("%s\n", str1);
	return 0;
}

4.3 Simulation implementation of strcat 

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

char* my_strcat(char* dest, const char* src)//src 指向的字符串是不改变内容的,所以用 const 修饰
{
	assert(dest && src);//确保两个指针有效
	char* ret = dest;
	while (*dest)
		dest++;//先找到 dest 指向的数组的第一个 '\0' 的位置
	while (*dest++ = *src++)//拷贝
		;
	return ret;
}
int main()
{
	char str1[50] = "row row row your boat,";
	char* str2 = "gently down the stream";
	my_strcat(str1, str2);
	printf("%s\n", str1);
	return 0;
}

5. strncpy - length-limited string copy

5.1 Declaration and Use of strncpy

The difference between strncpy and strcpy is that strncpy has one more parameter . This parameter is an unsigned integer , that is, you can customize how many bytes of content to copy . This greatly facilitates our use and improves the flexibility of the C language.

5.2 Usage of strncpy

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

int main()
{
	char str1[20] = "row your boat";
	char str2[] = "hello world";
	strncpy(str1, str2, 3);//我们从 str2 中拷贝三个字节的内容到 str1 去
	printf("%s\n", str1);
	return 0;
}

 

 We can see that the output is very strange, because when we only copy three bytes of content, strncpy will not add '\0' at the back (that is, copy as much content as we want) , which is As a result, we can see the contents of the str1 array before copying.

5.3 Simulation implementation of strncpy

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

char* my_strncpy(char* dest, const char* src, unsigned int num)
{
	assert(dest && src);//确保两个指针有效
	char* ret = dest;

	while (num--)//拷贝几个字节
	{
		*dest = *src;
		dest++;
		src++;
	}

	return ret;
}
int main()
{
	char str1[20] = "row your boat";
	char str2[] = "hello world";
	my_strncpy(str1, str2, 3);
	printf("%s\n", str1);
	return 0;
}

6. strncmp - Length-limited string comparison

6.1 Declaration and Use of strncmp

The functions of strncmp and strcmp are exactly the same, and the principle is exactly the same. That is to say, if you master strcmp, you can master strncmp. strncmp just has one more parameter than strcmp . This parameter is an unsigned integer representing bytes. That is, how many bytes we want to compare. We can observe the declaration of this function and the meaning of each parameter through the cplusplus website.

6.2 Usage of strncmp

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

int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret=strncmp(str1, str2,3);//我们只想比较字符串的前三个字节
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

 

6.3 Simulation implementation of strncmp

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

int my_strncmp(const char* str1, const char* str2, unsigned int num)//两个字符串的内容都不需要变,所以用 const 修饰
{
	assert(str1 && str2);
	while (num-- && *str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main()
{
	char* str1 = "abbbcd";
	char* str2 = "abbbdd";
	int ret = my_strncmp(str1, str2, 3);//我们只想比较字符串的前三个字节
	if (ret > 0)
		printf("str1 > str2\n");
	else if (ret < 0)
		printf("str1 < str2\n");
	else
		printf("str1 == str2\n");
	return 0;
}

7. strncat - Append a string with limited length

7.1 Declaration and Use of strncat

In the same way, if you master strcat, you can master strncat. strncat has an additional parameter of unsigned integer whose meaning represents the number of bytes. That is, we can customize how many characters we want to append to the end of another string. We can observe the declaration of strncat and the meaning of each parameter through the cplusplus website.

 

7.2 Usage of strncat

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

int main()
{
	char str1[50] = "row row row your boat,";
	char str2[] = "gently down the stream";
	strncat(str1, str2, 6);//我们只想追加 6 个字节的字符到 str1 中
	printf("%s\n", str1);
	return 0;
}

 If we pay attention here, we will find a problem. The last 6 bytes of characters we append do not contain '\0' , but when the final output is printed it seems to have been assigned a '\0' at the end of the string. Then this has to mention the characteristics of strncat, that is, strncat will add '\0' after the string to be appended .

 7.3 Simulation implementation of strncat

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

char* my_strncat(char* dest, const char* src, unsigned int num)//str2 中的字符串不需要被修改,所以用 const 修饰
{
	assert(dest && src);//确保两个指针是有效指针
	char* ret = dest;//记录返回值

	while (*dest)//先找到 dest 指向的 '\0' 的位置
		dest++;
	while (num-- && (*dest++ = *src++) )//拷贝限制的字节数
		;
	*dest = '\0';

	return ret;

}
int main()
{
	char str1[50] = "row row row your boat,";
	char str2[] = "gently down the stream";
	my_strncat(str1, str2, 8);
	printf("%s\n", str1);
	return 0;
}

summary

We covered a number of unrestricted-length string functions and restricted-length string functions above. So what's the difference between restricted and unrestricted? First of all , the flexibility of unrestricted string functions is relatively low , because only the whole string can be manipulated. However , the flexibility of the restricted string function is relatively high, and the number of characters to be manipulated can be customized. Also, limited-length string functions are safer than unrestricted-length string functions . Note that restricted is safer than unrestricted.

8. strstr - string search

8.1 Declaration and Use of strstr

strstr is literally two strings. Then its meaning is to find another string in one of the strings . We can observe the declaration of strstr and the meaning of each parameter through the cplusplus website.

We can know some principles of strstr by translating it. If the string 2 is found in the string 1, then the first address of the string 2 in the string 1 is returned. If the string is not found, a null pointer is returned .

8.2 Usage of strstr

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

int main()
{
	char* str1 = "row row row your boat,gently down the stream";
	char* str2 = "row your boat";
	char* ret = strstr(str1, str2);//在 str1 中查找 str2 
	printf("%s\n", ret);
	return 0;
}

It can be seen that the return value is the first address of the  first occurrence of str2 in str1.

8.3 Mock Implementation of strstr

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

char* my_strstr(const char* str1, const char* str2)//不需要改变其内容,用 const 修饰
{
	assert(str1 && str2);//避免是无效指针
	const char* s1 = str1;
	const char* s2 = str2;
	const char* cp = str1;//这个指针变量是至关重要的
	while (*cp)
	{
		s1 = cp;
		s2 = str2;

		//在 str1 中查找 str2 的核心循环
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')//查找完成
			return (char*)cp;

		cp++;
	}
	return NULL;
}
int main()
{
	char* str1 = "row row row your boat,gently down the stream";
	char* str2 = "row your boat";
	char* ret = my_strstr(str1, str2);
	printf("%s\n", ret);
	return 0;
}

Let's explain the idea in detail  by drawing a picture.

 

 

 

 9. strtok - String Slicing

9.1 Declaration and usefulness of strtok

For this function, we only need to understand the basic usage. We use the cplusplus website to observe the declaration of strtok and the meaning of each parameter.

This English paragraph is too long, let me explain the core part: we provide two parameters to strtok, one is a string, and the other is the token to be cut. If the token appears in the string, the position will be modified to '\0' and the address of the string before the token is returned . If you want to pass parameters twice, you only need to pass a null pointer.

9.2 Usage of strtok

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

int main()
{
	char* str1 = "row@row~row%your^boat,gently@down~the^stream";
	char* str2 = "@~%^";

	//将 str1 拷贝至 tmp 数组,这样不会丢失 str1 的原始数据
	char tmp[50] = { 0 };
	strcpy(tmp, str1);

	char* ret = NULL;
	for (ret = strtok(tmp, str2); ret != NULL; ret = strtok(NULL, str2))
	{
		printf("%s ", ret);
	}
	return 0;
}

10. strerror - error code parsing

10.1 Declaration and Use of strerror

One point we need to popularize is that in the C language, when a program error occurs, there is a hidden global variable errno , which is an integer, such as 0, 1, 2, 3, .... etc. They all represent different error messages, and the role of strerror is to translate this error code . We can observe the declaration of strerror and the meaning of each parameter  through the cplusplus website.

10.2 Usage of strerror

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

int main()
{
	FILE* p;
	p = fopen("test.txt", "r");//在我们的工程目录下并没有 test.txt 这个文件
	if (p == NULL)//那么打不开 p 就是一个空指针
	{
		printf("%s\n", strerror(errno));//这里就会解释为什么是空指针的原因
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_59913110/article/details/125657140