String functions and character functions

1. Strlen
seeking results?

#include<stdio.h>
int main()
{
    
    
	if (strlen("abc") - strlen("abcdef") > 0)
	{
    
    
		printf("hehe\n");
	}
	else
	{
    
    
		printf("haha\n");
	}
	return 0;
}

What strlen returns is a (size_t) unsigned int type number.
So the result returned is hehe, because 3-6 = -3 but it is stored in the memory in the form of complement, and the return should be a value of type size_t. The computer thinks that the complement of -3 is the original code, so this Is a large positive number
strlen in two ways

#include<assert.h>
//①计数器写法
int my_strlen(const char* str)
{
    
    
	int count = 0;
	assert(str != NULL);
	while (*str != '\0')
	{
    
    
		count++;
		str++;
	}
	return count;
}
//如果这里使用我们的my_strlen这个函数去求上面的my_strlen("abc") - strlen("abcdef") 得到的结果就应该是haha,因为这里我们自己所设定的返回值是int类型

//②递归写法(不创建临时变量,写一个求字符串长度的代码)
int my_strlen(const char* str)
{
    
    
	if (*str == '\0')
	{
    
    
		return 0;
	}
	else
	{
    
    
		return 1 + my_strlen(str + 1);
	}
}

String functions with unlimited length
Sometimes the destination space is not big enough. If you copy the source string to the target space, even if the program crashes, it will still display the result you want.
2.strcpy
① The source string must end with'\0'
char arr2[] = {'b','i','t'}; If you copy in this form, you will find that he cannot find'\0', It is very likely to cause out-of-bounds access
②The'\0' in the source string will be copied to the target space
③The target space must be large enough to ensure that the source string can be stored
④The target space must be variable
char* p = "abcdef "; This is also wrong, because this is a constant string, immutable

char* my_strcpy(char* dest, const char* src)
{
    
    
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
	while (*src != '\0')
	{
    
    
		*dest = *src;
		dest++;
		src++;
	}
	return ret;
	
int main()
{
    
    
	char arr1[] = "abcdefghi";
	char arr2[] = "bit";
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

The above code is not concise enough, this code is the most perfect

char* my_strcpy(char* dest, const char* src)
{
    
    
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
	//拷贝src指向的字符串到dest指向的空间,包含'\0'
	while (*dest++ = *src++) // 解引用的优先级比++高
	{
    
    
		;
	}
	//返回目的地空间的起始地址
	return ret;
}

3.strcat (string append function)
①The source string must end with'\0'
②The target space must be large enough to accommodate the content of the source string. The
target space is not large enough.
Insert picture description here
For this code, you will see the results displayed above, but the program also crashed because the space in arr1 is not enough, and the contents in arr2 cannot be directly appended.
Simulate strcat

char* my_strcat(char* dest, const char* src)
{
    
    
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
	//1.找到目的字符串的'\0'
	while (*dest != '\0')
	{
    
    
		dest++;
	}
	//2.追加
	while (*dest++ = *src++)
	{
    
    
		;
	}
	return ret;
}
int main()
{
    
    
	char arr1[30] = "hello";
	char arr2[] = "world";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

4. The strcmp (string comparison)
Insert picture description here
standard stipulates: if the
first string is greater than the second string, a number greater than 0 will be returned
. If the first string is equal to the second string, it will return 0 if the
first string is less than The second string returns a number less than 0.
So does strcmp compare the two strings which is longer?

int main()
//比较'a' 和'c'哪一个ASCII的值更大,在VS编译器下,直接就判断出来了第一个字符串大于第二个字符串
	char* p = "abcdef";
	char* pp = "crgjk";
	
	//第一个字符一样时,顺序比较下一个字符的大小
	char* p = "abcd";
	char* pp = "aced"

	//	相等的时候
	char* p = "abcd";
	char* pp = "abcd"
}

Is it because the length of the first string is 6 and the length of the second string is 5, so the first one is greater than the second? No, strcmp compares the size of the first character of the string (under the VS compiler, if the first character of string 1 is greater than the first character of the second string, it will directly return a number greater than 0 (usually 1) ) If the two first characters are the same size, compare the second character and push down the order.
Simulate strcmp

int my_strcmp(const char* str1, const char* str2)
{
    
    
	assert(str1 != NULL); 
	assert(str2 != NULL);
	//比较
	while (*str1 == *str2)
	{
    
    
		if (*str1 == '\0')
		{
    
    
			return 0;  //相等
		}
		str1++;
		str2++;
	}
	//vs编译器下实现的结果
	if (*str1 > *str2)
		return 1; // 大于
	else
		return -1; // 小于
	//gcc编译器下返回的结果
	//return (*str1 - *str2);
}
int main()
{
    
    
	char* p1 = "abcdef";
	char* p2 = "abcqwe";
	int ret = my_strcmp(p1, p2);
	printf("ret = %d\n", ret);
	return 0;
}

Length-limited string function
strncpy ①Copy
num characters from the source string to the target space
②If the length of the source string is less than num, after copying the source string, add 0 to the end of the target until num
strncat
strncmp
int strncmp(const char* string1,const char* string2,size_t count)

strstr---------Search string function If
you find it, you will return to me the address of the string you find. If you don't find it, you will return to me a NULL. The implementation logic of this function is quite complicated and needs to be repeated many times in the follow-up.

#include<assert.h>
char* my_strstr(const char* p1, const char* p2)//  这里我只是需要查找,所以不会改变里面的内容
{
    
    
	assert(p1 != NULL);
	assert(p2 != NULL);
	char* s1 = NULL;
	char* s2 = NULL;
	char* cur = (char*)p1;//可能报警告//记住他们两个相等的的位置,方便返回地址和进行下一次继续判断(字符串还有可能是"abbbcdef"     "bbc")
	if (*p2 == '\0')   // 传过去的字符串p2有可能是空字符串的情况
	{
    
    
		return (char*)p1;
	}
	//在p1里面查找p2,如果p1是一个空字符串那就根本没有办法查找,但是当p1不是空字符串的时候,说明就是可以查找的,我用p1的第一个字符和p2的
	//第一个字符相比较,如果不一样,我让p1的指针往后走一下,在比较直到p1指向的和p2指向的字符相等了,然后让他们一起向后走

	while (*cur) // 只有第一个字符串不为空,才有查找的必要 
	{
    
    
		s1 = cur;
		s2 = (char*)p2; // 因为p2是一各const类型的,所以可能汇报警告,需要强制类型转换一下
		//循环停止的条件有三个
		//1.首先p1先找到了'\0' 说明找不到p2了
		//2.在p1里面把p2彻底找到了,且p2已结遇见了'\0'所以停止了
		//3.*p1 != *p2循环也要停下来的
		//    "abcde"  "def"   "abcdef"  "def"  
		while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
		//库里面的函数写法(*s1 && *s2 && !(*s1-s2))
		{
    
    
			s1++;
			s2++;
		}
		if (*s2 == "\0") // 唯有这个条件下说明查找到,但是你会发现代码写到这里的时候,p1和p2的值一直都在改变,但是当我想要返回地址的时候
			//我不知道该怎么返回了,所以这里需要把起始的地址保存在一个变量里面,好方便下一次的继续使用
		{
    
    
			return cur;
		}
		cur++;
	}
	return NULL;
}

strtok
①The strtok function finds the next mark in str, and ends it with \0, and returns a pointer to this mark (Note: The strtok function will change the string being operated on, so the string divided by the strtok function is generally They are all temporarily 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
③The first parameter of the strtok function NULL, the function will start at the saved position in the same string and find the next mark

int main()
{
    
    
	char arr[] = "[email protected]";
	char* p = "@.";
	char buf[1024] = {
    
     0 };
	strcpy(buf, arr);
	//切割buf中的字符串
	char* ret = NULL;
	for(ret = strtok(arr,p);ret !=NULL;ret = strtok(NULL,p))
	{
    
    
		printf("%s\n",ret);
	}
//这里之所以这么写,是因为你会发现在切割字符串的时候,只有第一次传字符串的首地址,其余都是传NULL,这样子的写法就要比下面的方法感觉好很多。





	char* ret = strtok(arr,p);
	printf("%s\n", ret);
	
	ret = strtok(NULL, p);
	printf("%s\n", ret);
	
	ret = strtok(NULL, p);
	printf("%s\n", ret);
	return 0;
}

strerror
can convert the error code into what we know.

Character function
#include<ctype.h> need to introduce the header file
Insert picture description here

int main()
{
    
    
	//char ch = 'w';
	//如果是小写就会返回一个大于0的数
	//int ret = islower(ch);
	//printf("%d\n",ret);

	//char ch = tolower('Q');
	//char ch = toupper('q');
	//putchar(ch);
	
	//把字符串内容全部转为小写
	char arr[] = "I Am A Student";
	int i =0;
	while(arr[i] != '\0')
	{
    
    
		if(isupper(arr[i]))
		{
    
    
			arr[i] = tolower(arr[i]);
		}
		i++
	}
	printf("%s\n",arr);
	return 0;
}

Guess you like

Origin blog.csdn.net/MEANSWER/article/details/109805310