库函数的讲解及模拟实现
引言
在C语言编程中,库函数是一组提供常用功能的函数集合,可以通过包含相应的头文件并链接相应的库来使用。这些函数涵盖了各种任务,从简单的输入输出到复杂的数据处理和算法实现。
本博客将深入探讨C语言中一些常用的库函数,包括它们的作用、使用方法以及一些示例。通过了解这些库函数,您可以更高效地编写C程序,节省时间和精力。
目录
1.字符函数
1.1 字符分类函数
在C语言中,字符分类函数用于对字符进行分类或者判断字符的特性。这些字符分类函数在处理输入、解析字符串以及实现某些文本操作时非常有用,例如判断密码强度、分析用户输入等。通过使用这些函数,可以轻松地识别和处理不同类型的字符,从而增强程序的健壮性和功能性。
这些函数通常包含在头文件 ctype.h
中,并提供了一系列用于检查字符属性的函数。
这些函数包括:
这些函数返回非零值(通常是1)表示字符具有相应的特性,否则返回0。
这些函数的使用方法都非常的类似,我们就讲解一个函数作为案例。
int islower (int c);
islower
是能够判断参数部分的c
是否为小写字母的。
通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,就返回0。
其他函数大家也可以在https://cplusplus.com/
的官网上查阅到。
示例 : 将字符串中的小写字母转为大写字母,其他字符不变。
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i = 0;
char str[] = "Test String.\n"; //将一个字符串放到了字符数组中
char c;
while (str[i])
{
c = str[i]; //将字符数组中的元素赋给c
if (islower(c)) //使用islower函数判断是否为小写字母
c -= 32; //是小写,就将其-32得到大写字母。因为大小写字符的ASCII码值相差32。
putchar(c); //不管是本身就是大写的字母,还是通过if判断并转换得到的大写字母,在这里都会被打印输出。
i++;
}
return 0;
}
1.2字符转换函数
C语言提供了2个字符转换函数:
int tolower (int c); //将参数传进去的大写字母转小写
int toupper (int c); //将参数传进去的小写字母转大写
上面的代码,我们是通过小写字母-32来达到小写字母转大写字母的效果,而我们有了字符转换函数之后,就可以直接使用tolower
函数来实现了。
示例
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c)) //用islower函数来判断是否为小写
c = toupper(c); //用toupper函数对其进行转换
putchar(c);
i++;
}
return 0;
}
2.字符串函数
2.1 strlen的讲解与使用
size_t strlen (const char *str); //作用:计算字符串长度
- 字符串以
\0
作为结束标志,strlen函数返回的是在字符串中\0
前面出现的字符个数(不包含\0
)。 - 参数指向的字符串必须要以
\0
结束。 - 注意函数的返回值为
size_t
,是无符号的(易错)。 - strlen函数的使用需要包含头文件。
示例
#include <stdio.h>
#include <string.h>
int main()
{
const char* str1 = "abcdef";
const char* str2 = "bbb";
if(strlen(str2)-strlen(str1)>0 //易错:如果是3 - 6 得到的是 -3 ,但是因为他返回的是无符号的,因此会得到一个非常大的正数
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
2.2 strcpy的讲解
char * strcpy (char * destination , const char * source); //作用:拷贝字符串
- 将源指针(
const char * source
)指向的C字符串复制到目标指针(char * destination
)指向的数组中,包括终止的空字符(并在该点停止)。 - 源字符串必须以
\0
结束。 - 会将源字符串中的
\0
拷贝到目标空间。 - 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可修改。地址指向的常量字符串则不行——常量字符串不可修改
2.3 strcat的讲解
char * strcat ( char * destination, const char * source ); //作用:追加字符串
- 将源字符串的副本追加到目标字符串中。目标字符串中的终止空字符被源字符串的第一个字符覆盖,并且在目标字符串中形成的新字符串的末尾包含一个空字符。
- 源字符串必须以
\0
结束。 - 目标字符串中也得有
\0
,否则没办法知道追加从哪里开始。 - 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- 字符串自己给自己追加会导致1.死循环 2.程序崩溃 。 因为:源字符串的
\0
被目标字符串更换为第一个字符的时候,目标字符串自己的\0
也被更换为第一个字符。
2.4 strcmp的讲解
int strcmp ( const char * str1, const char * str2 ) //作用:字符串的比较
- 该函数从每个字符串的第一个字符开始比较。如果它们相等,则继续比较后续字符,直到字符不同或直到达到终止空字符为止。
- 标准规定:
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
- 那么如何比较两个字符串呢? 比较两个字符串中对应位置上字符ASCII码值的大小。
2.5 strncpy的讲解
char * strncpy ( char * destination, const char * source, size_t num ); //作用:长度限制的拷贝字符串
- 将源字符串的前 num 个字符复制到目标字符串中。如果在复制了 num 个字符之前发现源 C 字符串的末尾(通过空字符标识),则目标字符串将被填充为零,直到总共写入了 num 个字符为止。
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
2.6 strncat的讲解与使用
char * strncat ( char * destination, const char * source, size_t num ); //作用:长度限制的追加字符串
- 将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个
\0
字符。 - 如果source 指向的字符串的长度小于num的时候,只会将字符串中到
\0
的内容追加到destination指向的字符串末尾。
示例
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[20];
char str2[20];
strcpy (str1,"To be "); //首先将两个字符串拷贝到字符数组中
strcpy (str2,"or not to be");
strncat (str1, str2, 6); //然后将str2追加到str1中,并限制只追加6个字符
printf("%s\n", str1);
return 0;
}
2.7 strncmp的讲解
int strncmp ( const char * str1, const char * str2, size_t num ); //作用:长度限制的字符比较
- 比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不一样,就提前结束,大的字符所在的字符串大于另外一个。如果num个字符都相等,就是相等返回0.
- 返回值如下:
- 如果在 str1 中的第一个字符与 str2 中相应位置的字符相比较,发现在 str1 中的字符具有比 str2 中字符更小的值,则这个函数会返回一个小于零的值。
- 如果两个字符串的内容相等,这个函数将返回零。
- 如果在 str1 中的第一个字符与 str2 中相应位置的字符相比较,发现在 str1 中的字符具有比 str2 中字符更大的值,则这个函数会返回一个大于零的值。
2.8 strstr的讲解与使用
char * strstr ( const char * str1, const char * str2); //作用:在一个字符串中搜索指定子字符串的出现位置
- 函数返回字符串str2在字符串str1中第⼀次出现的位置,并返回一个指向该位置的指针。
- 如果没有找到子字符串,则返回空指针。
- 字符串的比较匹配不包含
\0
字符,以\0
作为结束标志。
示例
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This is a simple string";
char * pch;
pch = strstr (str,"simple"); //搜素str中是否有字符串simple
strncpy (pch,"sample",6); //并替换成sample
printf("%s\n", str); //最后会打印"This is a sample string"
return 0;
}
2.9 strtok的讲解与使用
char * strtok ( char * str, const char * sep); //作用:按照指定的分隔符将字符串拆分为多个子字符串
- sep参数指向⼀个字符串,定义了用作分隔符的字符集合
- 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。
- strtok函数找到str中的下⼀个标记,并将其用 \0 结尾,返回⼀个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。)
- strtok函数的第⼀个参数不为NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
示例
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "192.168.6.111";
char* sep = ".";
char* str = NULL;
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
{
printf("%s\n", str);
}
return 0;
}
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
开启了一个循环,使用 strtok 函数来分割字符串 arr。在第一次循环中,使用 strtok(arr, sep)
获取第一个子字符串,并将其赋值给 str;之后在循环的每一次迭代中,调用 strtok(NULL, sep)
来获取下一个子字符串,直到没有更多的子字符串为止。
2.10 strerror的讲解与使用
char * strerror ( int errnum ); //作用:把参数部分错误码对应的错误信息的字符串地址返回来
在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头文件中说明
的,C语言程序启动的时候就会使用一个全局的变量errno来记录程序的当前错误码,只不过程序启动
的时候errno是0,表示没有错误,当我们在使⽤标准库中的函数的时候发生了某种错误,就会将对应
的错误码,存放在errno中,而一个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是
有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
示例
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n", strerror(errno));
return 0;
}
结果为
Error opening file unexist.ent: No such file or directory
3.内存函数
3.1 memcpy的讲解与使用
void * memcpy ( void * destination, const void * source, size_t num ); //作用:将源内存区域的内容复制到目标内存区域中
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
- 这个函数在遇到 ‘\0’ 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
示例
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
3.2 memmove的讲解与使用
void * memmove ( void * destination, const void * source, size_t num ); //作用:将内存中的数据块从一个位置复制到另一个位置
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
示例
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
结果为
1 2 1 2 3 4 5 8 9 10
3.3 memset的讲解与使用
void * memset ( void * ptr, int value, size_t num ); //作用:将指定内存区域的前 n 个字节设置为特定的值
- memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
示例
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
结果为
xxxxxxworld
3.4 memcmp的讲解与使用
int memcmp ( const void * ptr1, const void * ptr2, size_t num ); //作用:比较两个内存区域的内容是否相等
- 比较从ptr1和ptr2指针指向的位置开始,向后的num个字节。
- 返回值如下:
- 如果两个内存块中的第一个字节(按照无符号字符值进行比较)在ptr1中的值小于ptr2中的值,则memcmp函数返回一个负值。
- 如果两个内存块的内容相等,则memcmp函数返回0。
- 如果两个内存块中的第一个字节(按照无符号字符值进行比较)在ptr1中的值大于ptr2中的值,则memcmp函数返回一个正值。
示例
#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}
到此,库函数的讲解就全部结束了。希望可以帮到你~