C语言字符串函数

1、strlen

size_t strlen(const char * str);strlen函数声明

strlen计算字符串的长度,寻找\0结束。

int len = strlen("abcedf");//字符串结尾自动带有\0,并且一个字符是一个字节
printf("%d\n", len);
char arr3[] = { 'a','b','c','d','e' };
int len1 = strlen(arr3);//随机值,因为一个字符后面没有\0,所以\0不知道什么时候出现
printf("%d\n", len1);

运行结果:
在这里插入图片描述
自己实现strlen功能:

//const修饰的*str,表示str指向的东西在这里面是不能修改的
int my_strlen(const char* str)
{
	int count = 0;
	//assert断言函数,如果括号内为true则继续执行,反之报错退出
	assert(str != NULL);
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}
int main()
{
    int len2 = my_strlen("abcedf");
    printf("%d\n", len2);
    return 0;
}

运行结果:
在这里插入图片描述

strlen返回值:

strlen函数原型是size_t类型的,size_t==unsigned int-无符号整型;

if ((strlen("abc") - strlen("abcdef")) > 0)
{
        printf("haha\n");
}
else
{
        printf("hehe\n");
}

运行结果:

3-6=-3,要当成无符号整型3
在这里插入图片描述

2、strcat、strnact

char* strcat(char* destination, const char* source);strcat函数声明-字符串追加

char* strncat(char* destination, const char* source, size_t count);strncat函数声明-字符串追加

注意事项:

  1. destination字符串足够大,能够包含source。
  2. destination必须是可以更改的;常量字符串是不行的。
  3. 包含’\0’

追加字符串strcat,但是不能用到自己给自己追加,追加字符串strncat,第三个参数是追加几个变量,注意:追加后不要超过原数组的长度。

char arr1[30] = "abc";
char arr2[] = "de";
strcat(arr1, arr2);
strncat(arr1, arr1,5);
printf("%s\n", arr1);

运行结果:
在这里插入图片描述
自己实现strcat函数:

char* my_strcat(char* dest, const char* src)
{
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
	while (*dest != '\0')
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
    	char arr521[30] = "abcdef";
	char arr522[] = "xyz";
	my_strcat(arr521, arr522);
	printf("%s\n", arr521);
}

运行结果:
在这里插入图片描述

3、strcpy、strncpy

char* strcpy(char* destination, const char* source);strcpy函数声明-字符串复制

长度不受限制的字符串函数,遇到’\0’停止

注意事项:

  1. destination字符串足够大,能够包含source。
  2. destination必须是可以更改的;常量字符串是不行的。
  3. 包含’\0’
char arr411[] = "abcdef";
char arr412[] = "xyz";
strcpy(arr411, arr412);
printf("%s\n", arr411);

运行结果:
在这里插入图片描述
自己实现strcpy函数:

char* my_strcpy(char* dest, const char* src)
{
	assert(dest != NULL);
	assert(src != NULL);
	char* ret = dest;
	while(*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
    	char arr421[] = "abcdef";
	char arr422[] = "xyz";
	my_strcpy(arr421, arr422);
	printf("%s\n", arr421);
}

运行结果:
在这里插入图片描述
char* strncpy(char* destination, const char* source, size_t count);strncpy函数声明-字符串复制

长度受限制的字符串函数

char arr61[10] = "abcdefeee";
char arr62[] = "bit";
strncpy(arr61, arr62, 6);
printf("%s\n", arr61);

arr62只有三个字符,后面的三个应’\0’替代
在这里插入图片描述
运行结果:
在这里插入图片描述

4、strcmp、strncmp

int strcmp(const char* str1, const char* str2);//strcmp函数声明-字符串比较

首先比较第一个字符,相对再比较第二个,在vs里面大于返回1,小于返回-1,等于返回0;在linux-gcc编译器里面大于返回一个大于0的数,小于返回一个小于0的数,等于返回0;所以不能用返回值==1/-1来判断;最好是>0或者<0。

char* p1 = "abcdef";
char* p2 = "abcdefs";
int ret1 = strcmp(p1, p2);
printf("%d\n", ret1);

运行结果:
在这里插入图片描述
自己实现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++;
	}
	if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}
int main()
{
    	char* p1 = "abcdef";
	char* p2 = "abcdefs";
	int ret1 = my_strcmp(p1, p2);
	printf("%d\n", ret1);
}

运行结果:
在这里插入图片描述
int strncmp(const char* str1, const char* str2, size_t count);strncmp函数声明-字符串比较

char* p3 = "abcdef";
char* p4 = "abcd";
int ret2 = strncmp(p3, p4, 4);
printf("%d\n", ret2);

运行结果:
在这里插入图片描述

5、strstr

char* strstr(const char* string, const char* str);strstr-字符串查找

返回第一次遇到字串的第一个字符的地址

char* p5 = "aaaeeffddd";
char* p6 = "ef";
char* ret3 = strstr(p5, p6);
if (ret3 == NULL)
{
        printf("字串不存在");
}
else
{
        printf("%s\n", ret3);
}

运行结果:
在这里插入图片描述
自己实现strstr函数:

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 != NULL);
	assert(str2 != NULL);
	char* st1;
	char* st2 = (char*)str2;
	while (*str1 != '\0')
	{
		st1 = (char*)str1;
		while ((*str2 != '\0') && ( * str1 == *str2))
		{
			str1++;
			str2++;
		}
		if (*str2 == '\0')
		{
			return st1;
		}
		str1 = st1;
		str2 = st2;
		str1++;
	}
	return NULL;
}

5、strtok

char* strtok(char* str, sonst char* sep);strtok-字符串分割

字符串分割会改变字符串的元素,所以最好复制一个字符串用来分割。

分割原理:找到分隔符后用’\0’代替,返回第一个字符,如果再分割此字符串只需要传入NULL指针,如果中间分割其他字符串,再分割此字符串需重新传入字符串,并且是从头开始查询。

char arr81[] = "sjsdhaj@sadjwa.dhwiao*dajiowa";//要分割的字符串
char* p7 = "@*.";//在这三种字符处分割:@和*和.
char buf11[1024] = { 0 };
char buf12[1024] = { 0 };
strcpy(buf11, arr81);
strcpy(buf12, arr81);

char* ret4 = strtok(buf11, p7);
printf("1%s\n", ret4);
ret4 = strtok(NULL, p7);
printf("2%s\n", ret4);
ret4 = strtok(buf12, p7);
printf("3%s\n", ret4);
ret4 = strtok(NULL, p7);
printf("4%s\n", ret4);
ret4 = strtok(buf11, p7);
printf("5%s\n", ret4);
ret4 = strtok(buf11, p7);
printf("6%s\n", ret4);
ret4 = strtok(NULL, p7);
printf("7%s\n", ret4);
  1. buf11:“sjsdhaj\0sadjwa.dhwiao*dajiowa”,返回sjsdhaj
  2. 继续buf11:“sjsdhaj\0sadjwa\0dhwiao*dajiowa”,返回sadjwa
  3. buf12:“sjsdhaj\0sadjwa.dhwiao*dajiowa”,返回sjsdhaj
  4. 继续buf12:“sjsdhaj\0sadjwa\0dhwiao*dajiowa”,返回sadjwa
  5. buf11:“sjsdhaj\0sadjwa\0dhwiao\0dajiowa”,返回sjsdhaj,此时改掉的是buf中的*,“sjsdhaj\0sadjwa\0dhwiao*dajiowa”->“sjsdhaj\0sadjwa\0dhwiao\0dajiowa”,并返回头上的s,打印遇到第一个\0停止打印。
  6. 此时没有可改的,返回头上的s,sjsdhaj\0,输出结束
  7. 继续buf,但是没有可改的,返回NULL

运行结果:

在这里插入图片描述

6、字符函数

  1. islower判断是不是小写字符
  2. iscntrl-任何控制字符
  3. isspace-空白字符:空格,换页\f,换行\n,回车\r,制表符\t,垂直制表符\v
  4. isdigit-十进制数组0-9
  5. isxdigit-十六进制数字,包括所有十进制数字,小写字母a-f,大写字母A-F
  6. isupper-大写字母A-Z
  7. isalpha-字母a-z或A-Z
  8. isalnum-字母或者数字,0-9或a-z或A-Z
  9. ispunct-标点符号任何不属于数字和字母的图形字符(可打印)
  10. isgraph-任何图形字符
  11. isprint-任何可打印的字符,包括图形字符和空白字符
  12. tolower-转小写字符
  13. toupper-转大写字符
//如果是一个小写字母,则该函数返回非零值(true),否则返回 0(false)。
char ch11 = 'w';
char ch12 = 'W';
int ret = islower(ch11);
printf("%d\n", ret);
printf("%d\n", islower(ch12));

运行结果:
在这里插入图片描述
把大写字母转换成小写:

char ch21 = tolower('Q');
putchar(ch21);
printf("\n");
char ch22[] = "I Am A Student";
int i = 0;
while (ch22[i] != '\0')
{
        if (isupper(ch22[i]))
        {
                ch22[i] = tolower(ch22[i]);
        }
        i++;
}
printf("%s\n", ch22);

运行结果:
在这里插入图片描述

7、内存函数mem…

memcpy

void* memcpy(void* dest, const void* source, size_t num);num单位字节

从存储区 source 复制 num 个字节到存储区 dest

memcpy实例以及自己实现memcpy函数:

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		++(char*)dest;
		++(char*)src;
	}
	return ret;
}
int main()
{
	int arr11[] = { 1,2,3,4,5 };
	int arr12[5] = { 0 };
	int arr13[5] = { 0 };
	memcpy(arr12, arr11, sizeof(arr11));
	my_memcpy(arr13, arr11, sizeof(arr11));
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr12[i]);
	}printf("\n");
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr13[i]);
	}printf("\n");
}

运行结果:
在这里插入图片描述

memmove

void* memmove(void* dest, const void* src, size_t count);memmove处理内存重叠的情况

比如:arr[10]={1,2,3,4,5,6,7,8,9,10};把arr中3,4,5,6,7复制到1,2,3,4,5,输出为{3,4,5,6,7,6,7,8,9,10}。当前编译器memcpy也能实现memmove的效果,但是最好还是使用memmove。memcpy适合拷贝内存不重复的数据

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	if (dest < src)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			++(char*)dest;
			++(char*)src;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
        int arr21[10] = { 1,2,3,4,5,6,7,8,9,10 };
        memmove(arr21, arr21 + 3, 20);
        for (int i = 0; i < 10; i++)
        {
                printf("%d ", arr21[i]);
        }printf("\n");
        int arr22[10] = { 1,2,3,4,5,6,7,8,9,10 };
        my_memmove(arr22, arr22 + 2, 20);
        for (int i = 0; i < 10; i++)
        {
                printf("%d ", arr22[i]);
        }printf("\n");
}

运行结果:
在这里插入图片描述

memcmp

int memcmp(const void* str1, const void* str2, size_t num);比较内存

int arr31[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr32[10] = { 1,2,3,4,5,6,7,8,9,1 };
int ret1 = memcmp(arr31, arr32, 37);
printf("%d\n", ret1);

运行结果:
在这里插入图片描述

memset

void* memset(void* dest, int c, size_t count);内存设置函数

注意:容易用错,设置的是字节,而不是元素

char arr41[10] = "";
memset(arr41, '*', 10);
int arr42[10] = { 0 };
memset(arr42, 1, 10);//出错

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值