C语言字符串函数

1.strlen函数

size_t strlen( const char * str );

例:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	char arr[] = "asdfgh";
	size_t len = strlen(arr);
	printf("%zd\n", len);

	return 0;
}

strlen函数的返回类型是size_t

而无符号整形 - 无符号整形的结果还是无符号整形

2.模拟strlen函数的另一种方法(不使用临时变量):

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

size_t my_strlen(const char* p)//递归
{
	assert(p != NULL);
	if (*p != '\0')
	{
		return 1 + my_strlen(++p);
	}
	else
	{
		return 0;
	}

}
//不允许用临时变量的话可以考虑用递归

int main()
{
	char arr[] = "asdfgh";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);

	return 0;
}

3.strcpy函数

char *strcpy( char * strDest , const char * strSour );

后边拷到前边

返回的是strDest指向的地址

会自动补上\0,此意即~

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

int main()
{
	char arr1[] = "asdfgh";
	char arr2[30] = "****************";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	//输出asdfgh

	return 0;
}

~即将arr1完全地放入arr2中

该函数会一直找arr1的\0再将前边的内容存入arr2中

注:常量字符串不可修改

且:

源字符串必须以'/0'结束

目标空间必须足够大,以确保能存放源字符串

目标空间必须可修改

4.空指针本身就为假

5.模拟实现strcpy

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strcpy(char* arr1, const char* arr2)
{
	assert(arr1 != NULL && arr2 != NULL);
	size_t len = strlen(arr2);
	int i = 0;
	for (i = 0; i < len; i++)
	{
		arr1[i] = arr2[i];
	}

	return arr1;
}

int main()
{
	char arr2[] = "asdfgg";
	char arr1[30] = { 0 };
	my_strcpy(arr1, arr2);
	printf("%s\n", arr1);

	return 0;
}

6.NULL本质也是0

文档里的nul和NUL就是\0

7.strcat函数

char *strcat( char * strDest , const char * strSour );

后追加到前

返回的是前边字符串的起始地址

也是完全地将后边的/0传过去

目标字符串中也得有/0,否则没办法知道追加从哪里开始.

目标空间必须有足够的大,能容纳下源字符串的内容.

目标空间必须可修改.

用这个函数,字符串自己不能给自己追加

所以不要用strcat给自己追加字符串

模拟实现:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strcat(char* dest, const char* src)
{
	int i = 0;
	while (*(dest + i) != '\0')
	{
		i++;
	}//出来后i就找到了dest的\0的位置
	
	//开始更换
	int j = 0;
	while (*(src + j) != '\0')
	{
		*(dest + i) = *(src + j);
		j++;
		i++;
	}
	
	*(dest + i) = *(src + j);
	return dest;
}

int main()
{
	char arr1[30] = "Hello";
	char arr2[] = "World";
	my_strcat(arr1, arr1);
	printf("%s\n", arr1);

	return 0;
}

8.strcmp函数

int strcmp( const char * str1 , const char * str2 );

strcmp的模拟实现:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 != NULL && str2 != NULL);
	while (*str1 == *str2 && *str2 != '\0')
	{
		str1++;
		str2++;
	}

	if (*str1 > *str2)
	{
		return 1;
	}
	else if (*str1 < *str2)
	{
		return -1;
	}
	else
	{
		return 0;
	}

}

int main()
{
	printf("%d\n", my_strcmp("aafg", "aafg"));

	return 0;
}

9.%???中,???之间只要有d就是打印有符号数,???之间只要有u就是打印无符号数

strncpy函数

char *strncpy( char * Dest , const char * Src , size_t count );

复制完成之后是可以不放\0进去的

即你让我拷贝几个我就拷贝几个(绝对)

不够的话我就在后边补上\0

strncmp

int strncmp( const char * str1 , const char * str2 , size_t count );

加上count后函数就会给你比较前count个字符的大小,别乱搞

strncat函数

char *strncat( char * Dest , const char * Src , size_t count );

他会给你默认在后边追加上一个\0(会多追加一个\0)

count超出那个要追加的字符串长度时,追加完成后加上\0,函数就跑路了,不会给你加上更多的\0

11.字符串自己给自己追加的时候用strncat最合适

12.strstr函数

char *strstr( const char * str1 , const char * str2 );

在前边那个字符串当中找后边那个字符串的位置,如果有,则返回后边那个字符串在前边那个字符串中 第一次 出现的地址,没找到则返回NULL

13.strstr的模拟实现:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strstr(const char* str1, const char* str2)
{
	while(1)
	{
		while (*str1 != *str2)
		{
			if (*str1 == '\0' || *str2 == '\0')
			{
				return NULL;
			}
			str1++;
		}//出来设好重生点

		char* s1 = str1;
		char* s2 = str2;
		while (*s1 == *s2)
		{
			s1++;
			s2++;
			if (*s2 == '\0')
			{
				return str1;
			}
			if (*s1 == '\0')
			{
				return NULL;
			}
		}

		str1++;
	}
}

int main()
{
	char* a = "abcdef";
	char* b = "bcq";
	char* ret = my_strstr(a, b);
	printf("%s\n", ret);

	return 0;
}
相关推荐
碧海蓝天20222 分钟前
C++法则21:避免将#include放在命名空间内部。
开发语言·c++
CodeWithMe21 分钟前
【读书笔记】《C++ Software Design》第一章《The Art of Software Design》
开发语言·c++
Tanecious.2 小时前
C++--红黑树
开发语言·c++
tanyongxi664 小时前
C++ Map 和 Set 详解:从原理到实战应用
开发语言·c++
飒飒真编程5 小时前
C++类模板继承部分知识及测试代码
开发语言·c++·算法
森焱森5 小时前
一文理解锂电池充电、过放修复与电量测量:从原理到实战
c语言·单片机·架构
艾莉丝努力练剑6 小时前
【C语言】学习过程教训与经验杂谈:思想准备、知识回顾(五)
c语言·开发语言·数据结构·学习·算法
救赎小恶魔6 小时前
C++11的整理笔记
c++·笔记
岁忧6 小时前
(LeetCode 面试经典 150 题 ) 209. 长度最小的子数组(双指针)
java·c++·算法·leetcode·面试·go
小何好运暴富开心幸福6 小时前
分层架构的C++高并发内存池性能优化
c++·性能优化·架构