High-level C Language | Character Functions and String Functions--Analog Implementation of Functions

The processing of characters and strings in C language is very frequent, but C language itself does not have a string type, and strings are usually placed in constant strings or character arrays . String constants apply to string functions that do not modify them

1. Find the length of the string

strlen
size_t means that the strlen function returns an unsigned integer, str points to a string, and receives the address of the string

  • The string has ended with '\0', 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'
  • Note that the return value of the function is size_t, which is unsigned (error-prone)

1.1 Use of strlen

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	const char* str1 = "abcdef";
	const char* str2 = "bbb";
	if ((int)strlen(str2) - (int)strlen(str1) > 0)
	{
    
    
		printf("str2>str1\n");
	}
	else
	{
    
    
		printf("str1>str2\n");
	}
	return 0;
}

operation result:
insert image description here

Note: When using strlen to compare the size of two strings, it cannot be directly used for subtraction, because strlen returns an unsigned integer. For binary bits, the highest bit is the sign bit. When it is an unsigned bit, The highest bit will also be used for calculation, which will be a large number, so it can be cast to int type during calculation, or directly compare them (strlen(str2)>strlen(str1)), so that no calculation will occur

1.2 Simulation implementation of strlen function

#include <stdio.h>
int my_strlen(const char* str1)
{
    
    
	int count = 0;
	while ( * str1!='\0')
	{
    
    
		str1++;
		count++;
	}
	return count;
}
int main()
{
    
    
	char* str1 = "abcdef";
	int count = my_strlen(str1);
	printf("%d", count);
	return 0;
}

Running result:
insert image description here
Of course, it can also be simulated by recursive method, pointer minus pointer

2. String functions with unlimited length

2.1 Use of strcpy

insert image description here
Copy the source string pointed to by source to the destination string pointed to by destination, and return a pointer of char* type

  • The source string must end with '\0'.
  • Will copy the '\0' in the source string to the target space
  • target space must be mutable
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char* str1 = "abcdef";
	char str2[20] = {
    
     0 };
	strcpy(str2, str1);
	printf("str2=%s", str2);
	return 0;
}

operation result:
insert image description here

2.1.1 Simulation implementation of strcpy function

#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* str2, const char* str1)
{
    
    
	char* ret = str2;
	assert(str1 && str2);
	while (*str2++ = *str1++)
	{
    
    
		;
	}
	return ret;
}
int main()
{
    
    
	char* str1 = "abcdef";
	char str2[20] = {
    
     0 };
	char* ret = my_strcpy(str2, str1);
	printf("str2=%s", ret);
	return 0;
}

operation result:
insert image description here

assert is used to assert whether it is a null pointer, if it is, an error will be reported, if not, continue execution

2.2 Use of strcat

insert image description here
Connect the source string pointed to by source to the end of the string pointed to by destination, and the first character of the source string is written to the terminating null character position of the destination stringinsert image description here

  • Both the source string and the target string must end with '\0'
  • The destination space must be large enough to hold the contents of the source string.
  • target space must be modifiable
#include <stdio.h>
#include <string.h>
int main()
{
    
    
    char str1[20] = "hello";
	char* str2 = "bit";
	strcat(str1, str2);
	printf("str1=%s", str1);
	return 0;
}

operation result:
insert image description here

2.2.1 Simulation implementation of strcat function

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* str1, const char* str2)
{
    
    
	char* ret = str1;
	assert(str1 && str2);
	//寻找到'\0'的位置
	while (*str1)
	{
    
    
		str1++;
	}
	//开始拷贝
	while (*str1++ = *str2++)
	{
    
    
		;
	}
	return ret;
}
int main()
{
    
    
    char str1[20] = "hello";
	char* str2 = "bit";
	char* ret = my_strcat(str1, str2);
	printf("str1=%s", str1);
	return 0;
}

Running result:
insert image description here
So the question is, can the string be appended to itself? Using the simulated code to analyze,
insert image description here
first, the source and the target point to the same location, and the target finds the position of the terminating null character, and then copies it, copying h for the first time, and stops until the '\0' is copied, but the first copy At this time, the '\0' will be overwritten, and the '\0' will not be found in subsequent copies, and the endless loop will continue. So the answer is that it is best not to append strings to yourself.

2.3 Use of strcmp

insert image description here
Compare the characters at the same position, if they are equal, compare the next pair of characters, if they are not equal, determine which is bigger, and return the corresponding number, the return type is int type
insert image description here

  • If the first string is greater than the second string, return a number greater than 0
  • If the first string is equal to the second string, return 0
  • The first string is less than the second string, returns a number less than 0
#include <stdio.h>
#include <string.h>
int main()
{
    
    
    char* str1= "hello";
	char* str2 = "bit";
	int ret = strcmp(str1, str2);
	printf("ret=%d", ret);
	return 0;
}

operation result:
insert image description here

2.3.1 Simulation implementation of strcmp function

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* str1, const char* str2)
{
    
    
	assert(str1 && str2);
	//当比较到'\0'或者不相等时就可以停下来
	while (str1 && str2 && *str1++ == *str2++)
	{
    
    
		;
	}
	int ret=str1 - str2;
	if (ret > 0)
	{
    
    
		return 1;
	}
	else if (ret < 0)
	{
    
    
		return -1;
	}
	else
	{
    
    
		return 0;
	}
}
int main()
{
    
    
    char* str1= "hello";
	char* str2 = "bit";
	int ret = my_strcmp(str1, str2);	
	printf("ret=%d", ret);
	return 0;
}

operation result:
insert image description here

3. Introduction to length-limited string functions

3.1strncpy

insert image description here

  • Copies num characters from source string to destination space.
  • If the length of the source string is less than num, after the source string is copied, 0 will be appended after the target, until num.
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char str1[20] = {
    
     0 };
	char* str2 = "bit";
	strncpy(str1, str2,5);	
	printf("str1=%s", str1);
	return 0;
}

operation result:
insert image description here

3.2strncat

insert image description here

  • Appends the first num characters of the source string to the end of the destination string, with a terminating null character at the end.
  • If the length of the source string is less than num, it is only copied up to the terminating null character.
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char str1[20] = "hello";
	char* str2 = "bit";
	strncat(str1, str2,5);	
	printf("str1=%s", str1);
	return 0;
}

operation result:
insert image description here

3.3strncmp

insert image description here

This function starts comparing the first character of each string, and if they are equal, it continues to compare the following pairs of characters until a different character is encountered, a terminating null character is encountered, or both strings match num characters. .

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char str[][5] = {
    
     "R2D2", "C3PO","R2A6" };
	int n;
	puts("Looking for R2 astromech droids...");
	for (n = 0; n < 3; n++)
	{
    
    
		if (strncmp(str[n], "R2xx", 2) == 0)
		{
    
    
			printf("found %s\n", str[n]);
		}
		
	}
	return 0;
}

operation result:
insert image description here

Four, string search

4.1 Use of strstr

insert image description here

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not in str1. As the saying goes, the strstr() function is used to find whether a string contains another string and return the position of the first match.

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char str[] = "This is a simple string";
	char* pch;
	pch = strstr(str, "simple");
	strncpy(pch, "sample", 6);
	puts(str);
	return 0;
}

operation result:
insert image description here

4.1.1 Simulation of strstr function

#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
    
    
	assert(str1 && str2);//断言str1和str2是否为空指针
	char* cp = (char*)str1;
	char* sstr1 ;
	char* sstr2 ;
	//*str2为'\0'返回str1的地址
	if (!*str2)
		return (char*)str1;
	while(*cp)
	{
    
    
		int count = 0;
		sstr1 = cp;
		sstr2 = (char*)str2;
		while (sstr1 && sstr2 && *sstr1++ == *sstr2++)
		{
    
    
			;
		}
		if (!*sstr2)
			return cp;
		cp++;
	}
	return NULL;
}
int main()
{
    
    
	char str[] = "This is a simple string";
	char* pch = my_strstr(str, "simple");	
	puts(pch);
	return 0;
}

operation result:
insert image description here

4.2 strtok

insert image description here

  • The sep parameter is a string that defines the set of characters for the separator
  • The first parameter specifies a string containing zero or more tokens separated by one or more delimiters in the sep string.
  • The strtok function finds the next mark in str, ends it with '\0', and returns a pointer to this mark. (Note: The strtok function will change the string being manipulated, so the strings split using the strtok function are generally temporary copied content and can be modified.)
  • The first parameter of the strtok function is not NULL, the function will find the first mark in str, and the strtok function will save its position in the string.
  • If one parameter of the strtok function is NULL, the function will start at the saved position in the same string and search for the next token.
  • If no more tokens exist in the string, a NULL pointer is returned.
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char str[] = "[email protected]#566&520";
	char sep[] = "@.# & ";//分隔符,strtok找到str中下一个标记就是分隔符,找到之后会将分隔符置为'\0',所以最好拷贝一下内容
	//返回指向该标记的指针,同时返回分隔符前面字段的第一个字符的地址
	char arr[30];
	strcpy(arr, str);
	char* p = NULL;
	//当第一个参数不为NULL时,找到第一个标记,strtok会保存该标记的位置
	//当第一个参数为NULL时,函数将在同一个字符串中被保存的位置开始查找,直到下一个标记
	//如果字符串没有标记了,则返回空指针
	for (p = strtok(arr, sep); p != NULL; p = strtok(NULL, sep))
	{
    
    
		printf("%s\n", p);
	}
	return 0;
}

operation result:
insert image description here

5. Error message reporting

5.1str error

insert image description here

  • The error code is stored in errnum, the value of errnum is interpreted, and a string describing the error condition is generated, just like errno is set by a library function.
  • This function returns a pointer to a statically allocated string that should not be modified by the program. Further calls to this function may overwrite its contents (not required by a particular library implementation to avoid data races).
  • The error string produced by strerror may vary between system and library implementations.
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
    
    
	FILE* pFile;
	pFile = fopen("test.txt", "r");
	if (pFile == NULL)
	{
    
    
		printf("Error opening file test.txt:%s\n", strerror(errno));
		//也可以用perror
		perror(pFile);
	}
	return 0;
}

operation result:
insert image description here

Six, character operation

insert image description here
Character conversion:

int tolower(int c);//uppercase to lowercase
int toupper(int c);//lowercase to uppercase

#include <stdio.h>
#include <ctype.h>
int main()
{
    
    
	int i = 0;
	char str[] = "Test String.\n";
	char c;
	while (str[i])
	{
    
    
		c = str[i];
		if (isupper(c))//是大写返回真
			c=tolower(c);//转小写
		putchar(c);
		i++;
	}
	return 0;
}

operation result:
insert image description here

Seven, memory operation function

7.1 Use of memcpy

insert image description here

  • The function memcpy copies num bytes of data backwards from the location of source to the memory location of destination. Because the return type of the target and source is void*, it can receive a copy of any type of data.
  • This function does not stop when encountering '\0'.
  • If the source and destination overlap in any way, the result of the copy is undefined.
#include <stdio.h>
#include <string.h>
struct {
    
    
	char name[40];
	int age;
}person;
int main()
{
    
    
	char myname[] = "Pierre de Fermat";
	memcpy(person.name, myname, strlen(myname) + 1);
	printf("%s\n", person.name);
	return 0;
}

operation result:
insert image description here

7.1.1 Simulation of memcpy function

#include <stdio.h>
#include <assert.h>
void* my_memcopy(void* str2, const void* str1, size_t num)
{
    
    
	void* ret = str2;
	assert(str2 && str1);
	while (num--)
	{
    
    
		//完成每一对字节的交换
		*(char*)str2 = *(char*)str1;
		str2 = (char*)str2 + 1;
		str1 = (char*)str1 + 1;
	}
	return ret;
}
int main()
{
    
    
	int str1[20] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int str2[20] = {
    
     0 };
	int* pc = (int*)my_memcopy(str2, str1, 40);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", pc[i]);
	}
	return 0;
}

7.1.2 Overlapping of source and destination of memcpy

#include <stdio.h>
#include <assert.h>
void* my_memcopy(void* str2, const void* str1, size_t num)
{
    
    
	void* ret = str1;
	assert(str2 && str1);
	while (num--)
	{
    
    
		//完成每一对字节的交换
		*(char*)str2 = *(char*)str1;
		str2 = (char*)str2 + 1;
		str1 = (char*)str1 + 1;
	}
	return ret;
}
int main()
{
    
    
	int str1[20] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	//int str2[20] = { 0 };
	int* pc = (int*)my_memcopy(str1+2, str1, 20);//将12345复制到34567这个位置
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", pc[i]);
	}
	return 0;
}

The expected result is 12123458910, but it is:
insert image description here
this is because:
insert image description here
3 has been covered by 1, and when 3 is assigned to 5, it is also 1, and the same is true for 4. Therefore, the memcpy function is best not to have any overlaps, that is, memcpy only needs to implement non-overlapping copies, but overlapping copies can be implemented on VS, because of the difference in compilers.

7.2 Use of memmove

insert image description here

  • The difference with memcpy is that the source memory block and target memory block processed by the memmove function can overlap.
  • If the source space and the target space overlap, you have to use the memmove function to deal with it.
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	int arr[20] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	memmove(arr + 2, arr, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", arr[i]);
	}
	return 0;
}

Running result:
insert image description here
It can be seen from the result that memmove can realize overlapping, so how to simulate and realize this function?

7.2.1 Simulation of memmove function

analyze:
insert image description here

#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
    
    
	assert(dest && src);
	if (src < dest)
	{
    
    
		void* ret = src;
		//从后向前开始拷贝
		src = (char*)src + num-1;
		dest = (char*)dest + num-1;
		while (num--)
		{
    
    
			*(char*)dest = *(char*)src;
			src = (char*)src - 1;
			dest = (char*)dest - 1;
		}
		return ret;
	}
	else
	{
    
    
		void* ret = dest;
		while (num--)
		{
    
    
		//从前向后拷贝
			*(char*)dest = *(char*)src;
			src = (char*)src + 1;
			dest = (char*)dest + 1;
		}
		return ret;
	}
}
int main()
{
    
    
	int arr1[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = {
    
     0 };
	int* pc=(int*)my_memmove(arr1+2 , arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", pc[i]);
	}
	return 0;
}

operation result:
insert image description here

7.3memcmp

insert image description here

  • Compares the first num bytes of the memory block pointed to by pointer ptr1 with the first num bytes of the memory block pointed to by pointer ptr2, and returns 0 if they both match, or a value indicating which is greater if they do not match .
  • Note that, unlike strcmp, this function does not stop comparing after finding a null character.
#include <stdio.h>
int main()
{
    
    
	char* str1 = "alfjlkfafj";
	char* str2 = "alffljaoiogi";
	int n =memcmp(str1, str2, 8);
	if (n > 0)
		printf("str1>str2\n");
	else if (n < 0)
		printf("str2<str1\n");
	else
		printf("str1=str2\n");
	return 0;
}

Running result:
insert image description here
end~

Guess you like

Origin blog.csdn.net/weixin_68201503/article/details/131720009