这些c语言库函数你必须会!!!

需要引用string.h的几个字符串函数和内存函数

1.strlen(求字符串长度:使用频率90%)

size_t strlen(const char*)

1.给该函数输入一个char*的指针,会返回一个无符号的整数。

2.该函数是从当前指针开始向后遍历,遇到‘\0’停止,返回期间遇到的字符个数。

3.注意返回的是无符号的整数,所以当出现使用strlen-strlen时,得到的也是无符号整数,这点应该是此函数最大的坑!!!
4.来段代码压压惊:

#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "my favorite basketball player is kyrie irving";
	int ret = strlen(p);
	printf("%d", ret);
	return 0;
}	

2.strcpy (字符串拷贝:使用频率9%)

char* strcpy(char* destination, const char* source);

1.给该函数传入一个源头指针(你想copy的字符串的位置)和目的地指针(你想copy在哪),返回的是你传入的目的地指针。所以为什么第一个参数是char型指针,第二个是const char指针,因为传进来的源头指针我是要它带进来的字符串,肯定不能修改;而我本来就是要修改目的地指针区域的内容(默认copy也是一种修改),所以它不能const。
2.这个函数有点呆,它会无脑把源头字符串所有内容(包括‘\0’)都拷到目的地去。基于这种性质,导致了问题3。
3.千万注意:这个函数不能自己拷贝自己!!!(你细品2)如果真要自己拷贝自己的内容,后面会介绍到该函数的加强版,这就是为什么这个函数用的频率少,有加强版谁还用它啊。
4.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>


int main()
{
	char arr[] = "my favorite basketball player is kyrie irving";
	char* p = "her";
	printf("%s\n", strcpy(arr, p));
	return 0;
}

返回:her

3.strcat (字符串追加:使用频率9%)

char* strcat(char* destination, const char* source)

1.strcat函数和前面的strcpy的形式一样,只是前面的是原地拷贝,这是在当前destination字符串后追加source字符串。
2.同样的道理,strcat函数也会将source的字符串全部追加到destination后(包括‘\0’)。这就和strcpy一样,source里面的字符串必须含‘\0’,否则遇不到‘\0’,拷贝和追加都无法停止,导致程序的崩溃。
3.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>


int main()
{
	char arr[100] = "my favorite basketball player is kyrie irving";
	char* p = "her";
	printf("%s\n", strcat(arr, p));
	return 0;
}

返回:my favorite basketball player is kyrie irvingher

4.strcmp (字符串比较:使用频率9%)

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

1.这个函数就有点意思了,貌似形参和返回值和前面都有点不一样。首先strcmp是字符串比较,不需要修改某一个字符串,所以最好都用const修饰。而返回值类型为Int,实际上分为三种情况:str1和str2相等,返回0;str1>str2时,返回大于0的数(因为第一个参数为str1,所以听你安排);str1<str2,返回小于0的数。
2.这个函数会从各自字符串首元素地址开始,逐个字符比较(按字符的ASCII值比较),而且一定要分出个胜负才停止。比如两个字符要是相等,那就指针加一继续比,不相等更好,谁ASCII值大谁赢,知道遇到‘\0’停止,如果你到‘\0’位置两者一直相等,那行,算平局(即两字符串相等)。
3.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>


int main()
{
	char arr[100] = "my favorite basketball player is kyrie irving";
	char* p = "her";
	int ret = strcmp(arr, p);
	printf("%d", ret);
	return 0;
}

显然m的ADCII码值比h大,所以一定返回一个大于0的数,大家可以试试哦!

# 小结:前面几个函数相必大家已经了解的差不多了,我们来总结一下:对于strcpy,strcat,strcmp三个函数,都逃不开‘\0’,只有遇到‘\0’函数才能结束,这就不能满足我们想拷贝几个字符就拷贝几个字符、想追加几个字符就追加几个字符、想比较几个字符就比较几个字符的意愿,对此有一定的局限性。因此,这就是为什么使用概率很少的原因,因为接下来会介绍它们的加强版,有加强版谁还用他们啊!!!

5.strncpy、strncat、strncmp(加强版来了!!!使用频率:99%)

char* strncpy(char* destination, const char* source, size_t num);
char* strncat(char* destination, const char* source, size_t num);
int strncmp(const char* str1, const char* str2, size_t num);

1.想必大家也看出来了,这三个函数就是之前三个函数的加强版,原理几乎一样。只是其中多了一个size_t的参数,单位是字节,简而言之就是:你想拷贝几个字节就拷贝几个字节,你想追加几个字节就追加几个字节,你想比较几个字节就比较几个字节,这就摆脱了之前‘\0’的限制,变得实用性更强!
2.对于strcat和strncat而言,之前说两者最大的区别就在于前者不能自己追加自己的字符元素,而后者可以!
3.基于这两组函数用法都一样,这里就不上代码了,但是我想说的是:这组加强版函数更值得我们记忆,它们的应用场景是比较广的!

6.strstr (字符串中查找子字符串:使用频率:99%)

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

1.到目前为止,我觉得这个函数实现起来是最复杂的(当然也没那么复杂啦!能想到其中的算法就好了)。当然,我们主要是会用它就好了,不需要我们自己实现(但是最好还是自己会写哦)。
2.该函数使用也比较简单,传入两个字符指针str1和str2,并将它们置为const(因为只是查找,怕一不小心给他修改了)。如果在str1中找到了str2,那么返回str1中匹配到str2的位置(指针);如果没找到,返回空指针。
3.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>


int main()
{
	char arr[100] = "my favorite basketball player is kyrie irving";
	char* p = "kyrie irving";
	char* ptr = strstr(arr, p);
	printf("%s", ptr);
	return 0;
}

返回:kyrie irving
注意,这里的返回值是kyrie irving!但返回的可不是p的地址哦,而是arr数组中匹配到kyrie irving处的地址。

7.strtok (字符串分割:使用频率99%)

char* strtok(char* str, const char* sep);

1.其中str为一个你想分割的字符串,sep是由你指定的分割符组成的字符串。
2.strtok函数找到str中的第一个分割符,并将其用‘\0’结尾,返回一个指向该分割符的指针。
3.当你第一次使用strtok时,需要传参str和sep,此时你直接打印返回值时,只会打印str中第一个分割符位置前的内容;如果你想继续往后找,需要传参NULL(代替str,因为经过上一次传参,该函数的记忆功能使指针停在上一次结束的位置)和sep,此时再打印,返回str中第一个分割符和第二个分割符之间的内容;同理,后续操作同上,可以找完str,最后再返回NULL
4.因为strtok它是真的要修改str字符串,所以传参时最好不要传str,而是拷贝一份str用来分割。
5.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>


int main()
{
	char arr[100] = "my favorite basketball player is : kyrie irving";
	char* p = "  :"; //我里面包含了空格和;两种分割字符
	char* str = NULL;
	char arr1[100] = { 0 };
	strcpy(arr1, arr); //对应点4,先拷贝一份再分割
	for (str = strtok(arr1, p); str != NULL; str = strtok(NULL, p))  //第一个参数除了第一次传原字符串,后面都是传NULL,直到遍历完该字符串{
		printf("%s\n", str);
	}
	return 0;
}

返回:大家试一下手哦!

8.strerror(返回错误码所对应的错误信息:使用频率99%)

char* strerror(int errnum)

1.调用库函数出错时,会将错误码记录到errno(只是一个数字)中,此时和strerror配合使用,就能打印错误信息。
2.这个函数只需要会用就行,底层怎么实现的不需要关心。
3.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>


int main()
{
	FILE* p = fopen("1.txt", "r");
	if (p == NULL) printf("%s", strerror(errno));
	return 0;
}

返回:No such file or directory

#小结:这就是一些常用字符函数的介绍了,用好了一些oj题解决起来就会很方便,希望能和大家一起记忆,烂熟于心!同时,了解了前面几个字符函数,想必大家可能会问:如果我想拷贝和比较其他类型的数据,该怎么办呢,接下来我们一起了解一下几个内存函数。

9.memcpy(内存拷贝:使用频率9%)

memmove(内存移动:使用频率99%)

void* memcpy(void* destination, const void* source, size_t num)
void* memmove(void* destination, const void* source, size_t num)

1.首先从形式来看,和strncpy看起来差不多,只是strncpy的char* 换成了void* 。其实也不难理解,strncpy是字符函数,所以指针接收返回都需要用到指针char* ;而memcpy是内存函数,任何数据类型都是要储存在内存里面的,所以无法指定一个具体的指针类型,既然这样,选择void* 是最合适的!
2.void*的指针是非常宽容的,可以接受任意类型的地址,但不能对其直接解引用,需要强制类型转换。
3.该函数底层实现原理和strncpy几乎一样,只是strncpy是按字符逐个拷贝,memcpy是按字节逐个拷贝,后面的num即为你想拷贝的字符或字节个数。
4.想必大家也猜出来了,memmove其实就算memcpy的加强版!所以我们掌握memmove即可。那么两者有什么区别呢!我们都知道,数据在内存里面存储都有相应的地址,而地址有高地址低地址之分,则传入的destination和source指针必有大小之别,而memcpy其实是忽略了一些情况的,所以不是对所有的情况都能解决。而我们说memmove是memcpy的加强版,那肯定是完美的解决了这些缺陷,所以大家熟记memmove即可!
5.上代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

struct stu	
{
	char name[20];
	int age;
	char sex[10];
};

int main()
{
	struct stu s1 = { "qinjie", 22, "male" };
	struct stu s2 = { "yangzhu", 21, "female" };
	memmove(&s1, &s2, sizeof(struct stu));
	printf("%s %d %s\n", s1.name, s1.age, s1.sex);
	return 0;
}

返回:yangzhu 21 female

10.memcmp(内存比较:使用频率99%)

int memcmp(const void* ptr1, const void* ptr2, size_t num)

1.这个函数和strncmp实现原理也是一样的,这里也不再过多阐述,我们直接上代码吧!

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

struct stu	
{
	char name[20];
	int age;
	char sex[10];
};

int main()
{
	struct stu s1 = { "qinjie", 22, "male" };
	struct stu s2 = { "yangzhu", 21, "female" };
	int ret = memcmp(&s1, &s2, sizeof(struct stu));
	printf("%d\n", ret);
	return 0;
}

返回:-1

总结:今天给大家介绍了c语言的十个库函数,包括字符函数和内存函数。其中最重要最重要的就是那几个加强版了,在日常应用中实用性拉满。最后,希望能和大家一起学习,一起进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值