C/C++常见库函数集合
C/C++库函数
1.字符串常见库函数
在C/C++当中,字符串是比较常见的一个类型,对于它的操作也是有着许多的操作库函数。接下来会讲解一些比较常见的库函数。
1.1 strlen库函数
strlen库函数是一个获取字符串长度的库函数,计算‘\0’之前的字符。对应的头文件 #include<string.h>
strlen的参数:
size_t strlen ( const char * str );
参数:字符串起始地址,会计算该字符串’\0‘之前的字符个数。
返回值:返回一个无符号数值。
代码实现如下:
int main()
{
char str1[] = "haha";
int ret=strlen(str1);//strlen计算'\0'之前的字符
printf("%d\n",ret);
return 0;
}
输出结果:
以下是模拟实现strlen库函数的三种方法:
- 计数器统计法
计数器的思路:在str找到 ‘\0’ 之前循环一次,count就计数一次。
int my_strlen(const char* str)
{
assert(str!=NULL);//断言
int count = 0;//计数器
while (*str++)
count++;
return count;
}
- 递归法
递归法思路:递归一次就加一。
int my_strlen(const char* str)
{
assert(str!=NULL);
if (* str!= '\0')
return 1+my_strlen(str + 1);//str+1——递归一次指针向后加1.
else
return 0;
}
- 指针减去指针求解法
指针减去指针思路:指针减指针得到元素个数的绝对值。
int my_strlen(const char* str)
{
assert(str!=NULL);
char* cp = (char*)str;
while (*cp++);//循环找到'\0'的位置
cp = cp - 1;
return (cp - str);
}
1.2 strcpy库函数
strcpy库函数—复制字符串的功能。对应的头文件 #include<string.h>
strcpy的参数:
char * strcpy ( char * destination, const char * source );
第一个参数:目的地,指向要在其中复制内容的目标数组的指针。
第二个参数:来源地,要复制的 C 字符串。
返回值:返回一个指针
代码实现如下:
int main()
{
char str1[] = "hehe";
char str2[] = "haha";
strcpy(str1,str2);//将str2的内容复制到str1中
printf("%s\n",str1);
return 0;
}
输出结果:
模拟实现strcpy库函数:
char* my_strcpy(char* str1, const char* str2)
{
assert(str1&&str2!=NULL);
char* cp = str1;
while (*str1++=*str2++);
return cp;
}
1.3 strncpy库函数
这个strncpy库函数与strcpy库函数相比就是多了一个参数。
strncpy库函数的参数:
char * strncpy ( char * destination, const char * source, size_t num );
前面两个参数和strcpy是一致的。
第三个参数:size_t num—要从来源地复制的最大字符数。
size_t 是无符号整数类型。
代码实现:
int main()
{
char ch1[] = "hello";
char ch2[] = "china!!!";
//只是把china拷贝过去
strncpy(ch1,ch2,5);
printf("%s\n",ch1);
return 0;
}
输出结果:
1.4 strcat库函数
strcat库函数—追加字符串函数。
strcat库函数的参数:
char * strcat ( char * destination, const char * source );
第一个参数:目的地,指向目标数组的指针,该数组应包含 C 字符串,并且足够大以包含串联的结果字符串。
第二个参数:来源地,要追加的 C 字符串。这不应与目标重叠。
注意:目的地和来源地不得重叠
代码实现:
int main()
{
char ch1[30] = "hello";
char ch2[] = " China!!!";
//将ch2的字符追加到ch1上。
strcat(ch1,ch2);
printf("%s\n",ch1);
return 0;
}
输出结果:
模拟实现strcat函数
//模拟实现strcat函数
void my_strcat(char* c1, char* c2)
{
assert(c1&&c2!=NULL);
while (*c1!='\0')c1++;//让它找到'\0'的位置
while (*c1++ = *c2++);
}
1.5 strncat库函数
strncpy库函数的参数:
char * strncat ( char * destination, const char * source, size_t num );
前面两个参数和strcat库函数是一致的。
第三个参数:size_t num—要从来源地追加的最大字符数。
size_t 是无符号整数类型。
代码实现:
int main()
{
char p1[20] = "hello ";
char p2[] = "China!!!";
//在p1的后面追加China
strncat(p1,p2,5);
printf("%s\n",p1);
return 0;
}
输出结果:
1.6 strcmp比较函数
strcmp库函数—比较两个字符串的库函数
strcmp库函数的参数:
int strcmp ( const char * str1, const char * str2 );
两个参数:都是要比较的 C 字符串。
返回值:
第一个字符串大于第二个字符串,则返回大于0的数。
两个字符串相等返回0.
第一个字符串小于第二个字符串,则返回小于0的数。
代码实现:
int main()
{
char c1[] = "abcdef";
char c2[] = "bcdef";
//c1比c2小会返回一个小于0的数
int ret=strcmp(c1, c2);
printf("%d\n",ret);
return 0;
}
输出结果:
模拟实现strcmp
int my_strcmp(const char* c1,const char* c2)
{
assert(c1&&c2!=NULL);
while (*c1 == *c2&&*c1&&*c2)//注意判断c1和c2不等于'\0'
{
c1++;
c2++;
}
if ((*c1 - *c2) > 0)
{
return 1;//c1大于c2时,返回1
}
else if ((*c1 - *c2) < 0)
{
return -1;//c1小于c2时,返回-1
}
return 0;
}
优化后:
int my_strcmp(const char* c1,const char* c2)
{
assert(c1&&c2!=NULL);
while (*c1 == *c2 && *c1 && *c2)//注意判断c1和c2不等于'\0'
{
c1++;
c2++;
}
if (*c1 != *c2)
{
return (*c1 - *c2);
}
return 0;
}
1.7 strncmp函数
strncmp比strcmp也就多了一个参数。
strncmp的参数:
int strncmp ( const char * str1, const char * str2, size_t num );
前面两个参数:都是要比较的 C 字符串。
第三个参数:size_t num:要比较的最大字符数。
返回值也是跟前面的strcmp是一致的。
代码实现:
int main()
{
char str1[] = "abcdef";
char str2[] = "aggg";
//两个字符串比较3个字符
int ret=strncmp(str1,str2,3);
printf("%d\n",ret);
return 0;
}
输出结果:
1.8 strstr库函数
strstr库函数—查找子串的一个库函数
strstr库函数的参数:
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
第一个参数:要查找的字符串
第二参数:包含要匹配的字符序列的 C 字符串
返回值:指向 str1 中指定的整个字符序列在 str2 中首次出现的指针,如果序列在 str1 中不存在,则为 null 指针。
代码实现:
//strstr
int main()
{
char str1[] = "abcdefChina!abcdef";
char str2[] = "China!";
//从str1中找到str2
char* ret=strstr(str1,str2);
printf("%s\n",ret);
return 0;
}
输出结果:
模拟实现strstr库函数
char* my_strstr(const char* str1,const char* str2)
{
assert(str1&&str2!=NULL);
char* cp = str1;
char* s1 = NULL;
char* s2 = NULL;
if (*str2 == '\0')//判断str2是不是空字符串
{
return cp;
}
while (*cp)
{
s1 = cp;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)//两个字符串循环判断是不是相等
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;
}
cp++;
}
return NULL;
}
1.9 strerror库函数
strerror库函数—返回错误码,所对应的错误信息
头文件:#include<errno.h>
代码实现:
#include<errno.h>
int main()
{
//0---->No error
//1---->Operation not permitted
//2---->No such file or directory
printf("%s\n", strerror(2));
return 0;
}
输出结果:
1.10 strtok库函数
strtok库函数----以符号来分割字符串
strtok的参数:
char * strtok ( char * str, const char * delimiters );
第一个参数:要截断的字符串
第二个参数:包含分隔符字符的 C 字符串。
返回值
如果找到字符,则返回指向字符开头的指针。否则为空指针。
注意:该库函数第一次传参时,第一个参数是字符串数组,往后传参是NULL
代码实现:
int main()
{
char str1[] = "163@193*111.000";
char str2[] = "@*.";
char* ret = NULL;
for (ret = strtok(str1, str2); ret != NULL; ret = strtok(NULL, str2))
{
printf("%s\n",ret);
}
return 0;
}
输出结果:
2.判断字符函数
以下是一些判断字符函数
2.1isdigit库函数
isdigit库函数—是判断十进制数字的库函数
返回值:真不为0,假为0
头文件为:#include <ctype.h>
代码实现:
#include <ctype.h>
int main()
{
int ret = isdigit('9');
printf("%d\n",ret);
return 0;
}
输出结果:
2.2 islower库函数
islower库函数—判断是否为小写字母的库函数
返回值:真不为0,假为0
代码实现:
int main()
{
int ret=islower('s');
printf("%d",ret);
return 0;
}
输出结果:
2.3 isupper库函数
isupper库函数—判断是否为大写字母的库函数
返回值;真不为0,假为0
代码实现:
int main()
{
int ret = isupper('W');
printf("%d\n", ret);
return 0;
}
输出结果:
3.字符转换函数
3.1 tolower库函数
tolower库函数—将大写转换为小写字符
头文件是:#include <ctype.h>
代码实现:
int main()
{
char ch = 'W';//将大写转换为小写
printf("转换前:%c\n",ch);
printf("转换后:%c\n", (tolower(ch)));
return 0;
}
输出结果:
3.2 toupper库函数
toupper库函数—将小写字母转换为大写字母
头文件是:#include <ctype.h>
代码实现:
int main()
{
char ch = 'w';//将小写转换为大写
printf("转换前:%c\n",ch);
printf("转换后:%c\n", (toupper(ch)));
return 0;
}
输出结果:
4.常见的内存函数
4.1 memcpy库函数
memcpy库函数—内存拷贝函数
头文件:#include <string.h>
memcpy库函数的参数
void * memcpy ( void * destination, const void * source, size_t num );
第一个参数:目的地—指向要在其中复制内容的目标数组的指针,类型转换为 void* 类型的指针。
第二个参数:来源地—指向要复制的数据源的指针,类型转换为 const void* 类型的指针。
第三个参数:字节数—要复制的字节数。size_t 是无符号整数类型。
注意: size_t num—是字节个数,不是元素个数。
代码实现:
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
//将arr1中1 2 3 4 5 拷贝为0
memcpy(arr1, arr2, 20);
int i = 0;
for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
{
printf("%d ",arr1[i]);
}
printf("\n");
return 0;
}
输出结果:
模拟实现memcpy库函数(不能实现重叠拷贝)
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest&&src!=NULL);
//因为是void*所以强制类型转换为cahr*
char* ret = (char*)dest;
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
return ret;
}
4.2 memmove库函数
memmove库函数—处理内存重叠的拷贝情况
头文件:#include <string.h>
memmove的参数和memcpy一致
代码实现:
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//将12345拷贝到从3的地址开始
memmove(arr+2, arr , 20);
int i = 0;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
输出结果:
模拟实现memmove库函数:
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest&&src!=NULL);
char* cp = (char*)dest;
//判断是否内存重叠的情况
if (dest < src)//内存不重叠的情况
{
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
else//内存重叠的情况
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return cp;
}
4.3 memcmp库函数
memmcmp—比较两个内存块
头文件—#include <string.h>
memcpm的参数
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
第一个参数:指向内存块的指针。
第二个参数:指向内存块的指针。
第三个参数:要比较的字节数。
返回值—是和strcmp一致的
代码实现:
int main()
{
int arr1[] = {1,2,3,5,5,6,7};
int arr2[] = {1,2,3,4,5,6,7 };
//arr1与arr2进行比较
int ret=memcmp(arr1, arr2, 20);
printf("%d\n",ret);
return 0;
}
输出结果:
4.4 memset库函数
memset—填充内存块
头文件—#include <string.h>
memset库函数的参数:
void * memset ( void * ptr, int value, size_t num );
第一个参数:指向要填充的内存块的指针。
第二个参数:要设置的值。该值作为 int 传递,但该函数使用此值的无符号 char 转换填充内存块。
第三个参数:要设置为该值的字节数。size_t 是无符号整数类型。
返回值:返回指针类型
代码实现:
int main()
{
char str[30] = "HELLO CHINA";
//在str字符串后面添加三个感叹号
memset(str + 11, '!', 3);
printf("%s\n",str);
return 0;
}
输出结果:
总结
刚学玩关于常用库函数,就迫不及待的写这一篇博客。希望这篇文章能帮到你。