字符串函数的实现(笔记)

C语言字符串函数
C语言字符串函数在函数原型为string.h的头文件中,编写程序时直接调用即可

strlen
size_t strlen(char const *s)//作为参数,数组和指针形式一样,在这里用指针表达
返回s的字符串长度(不包括结尾的0)const作用是strlen保证不会修改当前的内容
strlen编写

#include <stdio.h>
#include <string.h>  //字符串头文件 

int mylen(const char *s)  //定义一个自己的字符串长度函数 
{                         //数组传入也是指针,用指针表达 
	int num = 0;          //const保证不会修改字符串 
	while ( s[num] != '\0')  //num为计数器,并且作为数组下标
	{
		num++;
	}
	
	return num;   //返回结果 
}

int main(int argc, char *agrv[])
{
	char line[] = "Hello";
	printf("strlen=%d\n", strlen(line));  //调用C语言内部的字符串长度函数,当前返回5
	printf("sizeof=%d\n", sizeof(line));  //结尾有‘\0’ 当前返回6
	printf("mylen=%d\n", mylen(line));
	
	return 0;
}

strcmp
strcpy
strstr
strcat
strchr

strcpy
char *strcpy(char restrict dst, const char restrict src)
把src字符串拷贝到字符串dst空间中去,restrict表示src和dst所占内存空间不重叠,返回dst为了让dst参与其他运算,投入给其他函数的参数
在这里插入图片描述
重叠时不能利用strcpy进行复制,不重叠时可进行复制计算
第一个参数是目的,第二个参数是源,源要求不能被改变,加const,而目的不需要

通常利用此函数进行字符串的复制
char dst = (char)malloc(strlen(src)+1);
//src是源字符串,但是源字符串可能不会实时存在,例如当一个函数参数需要字符串作为输入,此时函数得到的是字符串的首个位置的地址,其他值并没有被函数得到,而src作为输入,第一次被赋值"hello",当下一次赋值行为产生后可能被改变成为"world",但是运算需要第一次赋值参与(这样就使得不能保证函数参数所指向的那个地址存储的字符串实时存在),为了能够实现,需要向系统申请另一块空间进行保存,但是因为得到的是地址,并没有说明字符串具体的大小,这块内存的大小未知,所以利用动态内存分配解决,将src字符串复制到另一个变量保存(相当于复制到我这里保存),并将此变量作为函数进行输入。strlen(src)+1,加一是因为strlen只得到了字符串的有效长度,即存内容的长度,不包括结尾的0,+1是为了在dst里面也以字符串的形式保存,+1后得到的空间包含了结尾的0,结尾的0利用strcpy函数里面加入,使dst成为字符串
strcpy(dst, src);//接着做strcpy

写自己的strcpy(最简单的,不分配到多个核里面)

#include <stdio.h>
#include <string.h>

char *mycpy1(char *dst, const char* src) //数组版本 
{
	int idx = 0;  //定义并初始化下标 
	while( src[idx] != '\0' ) {  //其中条件可直接写为src[idx] 
		dst[idx] = src[idx];     //让dst中的每个元素等于src中的每个元素 
		idx++;                   //当循环到最后一位'\0'时,此时会跳出循环,跳出循环时,idx的值指向的数组的最后一位,此时并未赋值,dst字符串中并没有最后结束符,所以跳出循环后需要将最后一位赋值为0
	}
	dst[idx] = '\0';             //跳出后,在循环外面加入最后一位 
	return dst;                  //返回下标 
}

char  *mycpy2(char *dst, const char* src) //指针版本
{
	char *ret = dst;      //利用指针版本时,因为对地址进行了运算,循环到最后时dst已经被加到最后的地址位置了,需要在进入循环用另一个参数前对dst初始数值进行记录 
	while ( *src != '\0' ) //条件也可以拿掉后面的0 
	{
		*dst = *src;  //可不要后面两行,直接写为 *dst++ = *src++; 
		dst++;//指针地址运算
		src++;
	}
	*dst = '\0';
	return ret;
	/*上述赋值运算可直接写到while中,while(*dst++ = *src++);剩下空循环
	为了让代码更简洁,但是运行效率是一样的,循环内部无任何内容即可 
	*/
} 
int main(int agrc,char const *agrv[])
{
	char s1[] = "abc";
	char s2[] = "Abc";
	strcpy(s1, s2);
	
	return 0;
}

strcmp函数(compare)比较时不修改字符串
/*
strcmp 比较两个数组的大小是否相等
返回结果有-1 1 0(具体返回结果根据编译器不同而不同,具体是0,大于0,小于0三种情况)
不可以用两个数组 s1 和 s2直接比较
s1 == s2 这个时候比较的是两个数组地址是否相同,没有任何意义,数组的比较永远是false
if( strcmp(s1, s2) == 0 ) 比较两个字符串是否相等的写法
strcmp()其中参数是两个固定的参数
*/

#include <stdio.h>
#include <string.h>

char mycmp1( char const s1[], char const s2[] )  //第一种,利用while循环,条件判断 
{
	int idx = 0;
	while (s1[idx] == s2[idx] && s1[idx] != '\0')
	{
		if ( s1[idx] != s2[idx] ){
			break;
		} else if ( s1[idx] == '\0' ) {
			break;
		}
		idx++;
	}
	return s1[idx] - s2[idx];
}

char mycmp2( char const *s1, char const *s2 )   //第二种,省略中间判断 
{
	int idx = 0;
	while (s1[idx] == s2[idx] && s1[idx] != '\0')
	{
//		if ( s1[idx] != s2[idx] ){
//			break;
//		} else if ( s1[idx] == '\0' ) {
//			break;
//		}
		idx++;
	}
	return s1[idx] - s2[idx];
}
char mycmp3( char const *s1, char const *s2 ) //第三种,省略中间部分的变量,直接将数组看做指针,取地址后,对地址变量以及相对应数值进行操作 
{
//	int idx = 0;
	while (*s1 == *s2 && *s1 != '\0')  //相应写法要改变 
	{
		s1++;
		s2++;
//		if ( s1[idx] != s2[idx] ){
//			break;
//		} else if ( s1[idx] == '\0' ) {
//			break;
//		}
//		idx++;
	}
	return *s1 - *s2;
}


int main(int agrc, char const *agrv[])
{
	char s1[] = "abc";    //返回值小于0,表示str1小于str2,返回值大于0,表示str1大于str2,等于零表示相等 
	char s2[] = "Abc";    //strcmp有些返回差值,有些只返回0  -1  1三个数,与编译器有关,编译器不同,返回值情况不同 
	printf("strcmp(s1, s2) = %d\n", strcmp(s1, s2));    //具体的数值根据不同的编译器不同 
	printf("'a' - 'A' = %d\n", 'a' - 'A');
	printf("mycmp1(s1, s2) = %d\n", mycmp1(s1, s2));
	printf("mycmp2(s1, s2) = %d\n", mycmp2(s1, s2));
	printf("mycmp3(s1, s2) = %d\n", mycmp3(s1, s2));
	
	return 0;
}

字符串搜索函数
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
返回NULL表示没有找到

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
char* strchr(const char *s, int c);   从左向右在字符串中找到此字符出现的第一个位置 
char* strrchr(const char *s, int c);  从右向左在字符串中找到此字符出现的第一个位置 

返回NULL表示没有,非NULL表示出现的第一个指针 
返回值是指针,类型为char型 
*/
int main(int argc, char const *argv[])
{
	char s[] = "hello";            //定义一个字符串
	char *p = strchr(s, 'l');      //将指针p赋值为第一个l出现的位置
	printf("%p\n", strchr(s, 'l'));  //输出l的地址(16进制)
	printf("%d\n", strchr(s, 'l'));  //输出l的地址(10进制)
	printf("%s\n", p );              //输出p所指向的字符串,结果为llo
	p = strchr(p+1, 'l');            //将p重新赋值,使strchr函数从p+1地址位置重新开始找第一个l的地址,并赋值给p(利用strchr函数寻找第二个l 的地址),p+1的目的是使p指向第一个l后面的地址,并从此地址开始运算
	printf("%s\n", p );    //输出p所代表的字符串,输出结果为lo
	
	
	char *t = (char*)malloc(strlen(p)+1);//动态内存分配
	strcpy(t, p);
	printf("t = %s\n", t);   //将p所指的那个字符串拷贝到t中去
	free(t);
	
	char *a = strchr(s, 'l');  //找l前的字符串并输出
	char c = *a;
	*a = '\0';
	t = (char*)malloc(strlen(s)+1);
	strcpy(t, s);
	printf("%s\n", t);   //输出he
	free(t);
	/*
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200913104552720.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dsaDY1NDU2MjcxNg==,size_16,color_FFFFFF,t_70#pic_center)

	*/
	
	
	return 0;
}

字符串中寻找字符串
char * strstr(const char *s1, const char * s2);
字符串中寻找一个字符串
char * strcasestr(const char *s1, const char * s2);
字符串中寻找字符串,忽略大小写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值