[C Language] Common string functions and their error-prone uses (simple and in-depth study of strlen, strcpy, strcat)

Share several common string functions and their common mistakes

Table of contents

1.strlen

2.strcpy

3. broken


1.strlen

Directly upload the code

#include<stdio.h>
#include<string.h>
int main()
{
	int len = strlen("abcdef");
	printf("%d", len);
	return 0;
}

I believe everyone is very familiar with strlen. A string uses '\0' as the end mark of a string. The strlen function returns the number of strings that appear before '\0' in the string, excluding '\0' , but it should be noted that the return value of this function is size_t, which is what we call an unsigned number.

It is also very simple to test, just add \0 to the string to verify whether it really ends with \0

int main()
{
	int len = strlen("abc\0abc");
	printf("%d", len);
	return 0;
}

Then there is no doubt that the running result is 3

 It should also be noted that strlen is a function, and the string pointed to by the parameter must end with '\0', otherwise the accurate result cannot be calculated.

As follows we give a string without \0

int main()
{
	char arr[3] = { 'a','b','c' };
	int len = strlen(arr);
	printf("%d", len);
	return 0;
}

There is no \0 stored in my arr character array, so the computer will give a random value

 So we also said above that the return value of strlen is a number of type size_t (unsigned). So what is the result of running the following code?

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

So did you answer it correctly?

The result of strlen("abc") is 3, and the result of strlen("abcdef") is 6. They follow the mathematical logic and the result is -3, but we emphasize again that the return value of strlen is an unsigned number. So -3 will be output in complement form and is a positive number, so it must be ">",

Then there is how to customize the function to simulate and implement the strlen function

There are counter methods, recursion, pointer decrement pointer methods;

Below we implement it one by one

First is the counter

int my_strlen(const char* str)
{

}
int main()
{ 
	char arr[] = "bit";
	int len=my_strlen(arr);
	printf("%d", len);
	return 0;
}

The point we want to explain here is the return type of the custom function. The above mentioned type is size_t, but in our hands, why does it become an int type? Let’s take the above code as an example.

The return value of strlen in the library function is an unsigned integer. However, after the calculation in the above figure, the result should be -3, but the complement code in the computer will be converted into a very large positive integer. At this time, we must consider the purpose of our use. And the environment, the computer may consider that since the length is to be calculated, the length will not be less than 0, so the unsigned integer type is used, but according to our normal calculation logic, 3-6 should be calculated Equal to -3, so both types have their own say. As for adding const in front of the formal parameter is to protect the contents of our arr array from being changed;

Next is the function body content

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

For the counter method, of course we have to define a variable count as a counter. From the code, we can easily see that str is a pointer of type char*, pointing to the address of the first element in the arr array, and str is a pointer of type char*, pointing to arr. The address of the first element in the array. The basic array parameters must be clearly remembered. Go down and use the str pointer in the while loop. When the element in the address pointed to by this pointer is not '\0' when, then give count++; and move the address pointed to by the pointer one bit backward, and keep looping until the str pointer is dereferenced to '\0' and stop looping;

So that we can run the code without any problems

 This uses the counting method custom function to implement the strlen library function.

Next, use the recursive method to simulate the implementation of strlen.

Recursive implementation eliminates the need to create temporary variables

Let’s use the main function above as an example.

int main()
{ 
	char arr[] = "bit";
	int len=my_strlen(arr);
	printf("%d", len);
	return 0;
} 

 In fact, it is very simple. When we see the elements in the character array arr, the b in "bit" is not '\0', which means it is not the end. The length of the string is 1 + the length of "it". The length of "it" can be regarded as the length of 1+"t", so for longer strings we can do the same thing.

code show as below

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

When entering the function body, you must first determine whether the first element of the incoming array is '\0'. If it is not '\0', continue to let the 1+ pointer subscript be the address of the next element until the if judgment condition is not entered.

Let the code run

 The result is still 3, so the function recursive method does not need to create temporary variables;

The third method is to subtract the pointer from the pointer; the idea is also very simple: the address of the last element minus the address of the first element can be used to calculate the length of the string.

int my_strlen(const char* str)
{
	char* start = str;//start里面装的是首元素a的地址
		while (*str != '\0')
		{
			str++;
		}
		return str - start;
}

Define a char* type pointer in the function to store the first address element in the passed parameter. After entering the loop as above, let str++ be added. Note that it is only str++ that is added until \0, but the position of the start pointer is not Change, so after the loop ends, the str pointer points to the end of the string, and start points to the beginning, so subtracting the first address from the end is also the length of the string.

 

 The result is the same as the above two methods.

2.strcpy

That is, the meaning of string copy

Enter the code directly and also include the header file <string.h>

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = { 0 };
	strcpy(arr2, arr1);
	printf("%s", arr2);
	return 0;
}

The function of strcpy is to copy the contents of one array to another array.

Let’s go to the official website to check the basic information of this function.

 This function has two pointer type parameters. The destination in the previous parameter means the destination, and the source in the latter parameter means the source, so the meaning of this function is to copy the content of the following parameters to the previous parameter. Then let’s run the above code

 Then it is obvious that the contents of the arr2 array become the contents of the arr1 array;

Can the contents of arrays be exchanged like numbers?

It's definitely not possible

 If you write like this, an error will be reported. This is a grammatical error. We must not write like this. We must follow the rules of grammar and can only use strcpy.

Then follow the method code of the first function as follows:

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

 What will be the result?

 We only copied abc to the arr2 array. Of course, \0 will also be copied to the new string array.

So when there is no '\0' in our original string

int main()
{
	char arr1[3] = {'a','b','c'};
	char arr2[20] = { 0 };
	strcpy(arr2, arr1);
	printf("%s", arr2);
	return 0;
} 
 

A random value will appear 

 Therefore, the source string must end with \0, and \0 will be copied to the target space;

It should also be noted that the space of the target array must be large enough to ensure that the contents of the source string can be stored.

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[20] = "asdfghjkl";
	char arr2[5] = { 0 };
	strcpy(arr2, arr1);
	printf("%s", arr2);
	return 0;
} 
 

When we write the code like this, it is obvious that the target array is not large enough, and a stack overflow problem will occur.

 Another thing to note is that the target space must be able to be modified.

If I write the following piece of code, after running it, I will find

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

 The two locations conflict during writing, so the target space must be modified during writing.

Next is the custom simulation implementation of strcpy function

char* my_strlen(char* dest, const char* src)
{
	char* ret=dest;//函数要返回首元素地址,我们不妨将首元素地址先存起来
	assert(dest &&src);//断言确保两个地址相等
	while (*dest++ = *src++)//判段将两个指针解应用后的值相等,并且自加至\0 ,当自加至\0的时候,while(0),于是跳出循环
	{
		; 
	}
	return ret;//函数需要返回首元素地址,将开始存下来的首元素地址返回

}

Still need to pay attention to the return type of the function and the parameters passed.

In this way, we can copy \0 and stop when encountering \0.

 Then this can also implement array copy;

3. broken

The strcpy above can only overwrite the content. Now we are going to explain the append function, which means adding a string after the string. At this time, the strcat function is used

Let's look up the return type and parameters of the strcat function on the official website. We can see that it looks the same as strcpy. It also needs to include the <string> header file.

Demonstrate its usage with code

#define  _CRT_SECURE_NO_WARNINGS  1
#include<string.h>
#include<stdio.h>
int main()
{
	char arr1[20] = "hello ";
	char arr2[20] = "world";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

You can see that the contents of the arr2 array are appended to the arr1 array through the append function.

After debugging, we will conduct an in-depth study of the contents of the two arrays.

 We can see that in addition to hello, there is a space and a \0 in the arr1 array. This space was manually entered by us at the time. How does the function append be appended? Hit F10 again, let the code continue, and observe the contents of arr1 again

Walk!

 Note that red is the value changed after one step. Compared with the above, we find that the addition starts from \0 in the arr1 array.

So do we also have to have '\0' in the appended function?

 After debugging, we found that the array to be appended must also contain '\0' , otherwise an error will be reported. 

Therefore, the target space must be able to be modified, and the space must be large enough to accommodate character content. These conditions are indispensable.

 

The next step is to simulate and implement the strcat function

Also deal with the function return type and function parameters first.

char* my_strcat(char* dest,const char* src)
{

}

Like the above, the return type of the function is char*, and the following content must be added to the front, so the following content does not need to be changed and must be modified with const.

Next is the function body

As mentioned above, the source string is added after the first \0 in the target space, so our idea is to first find the first \0 in the target space, and then use strcpy to copy it into it;

char* my_strcat(char* dest,const char* src)
{
    while(*dest!='\0')//这个while循环用来寻找目标空间的第一个\0
    {
        dest++;
    }
    while(*dest++=*src++)//再用strcpy将其\0后的内容进行拷贝
    {
        ;
    }

}

But if we look closely, we will find that the return value is the address of the first element, but the address of the first element in the function body has been ++ed many times, so we need to save the address of the first element at the beginning. The code is as follows

char* my_strcat(char* dest,const char* src)
{
    char* ret=dest;
    while(*dest!='\0')//这个while循环用来寻找目标空间的第一个\0
    {
        dest++;
    }
    while(*dest++=*src++)//再用strcpy将其\0后的内容进行拷贝
    {
        ;
    }
    return ret;

}

This is a custom function that simulates the complete body of strcat

The code runs

 no problem at all

Hope the above content is helpful to you

Guess you like

Origin blog.csdn.net/wangduduniubi/article/details/129459917