“string.h“中的函数
摘要:本文详细介绍了C语言标准库"string.h"中的常用字符串处理函数,包括字符串长度计算(strlen)、内存设置(memset)、字符串复制(strcpy/strncpy/memcpy/memmove)、字符串比较(strcmp/memcmp)、字符串搜索(strchr/strstr)等函数的使用方法和注意事项。通过代码示例演示了各函数的正确用法,并特别强调了内存溢出的
"string.h"中的函数
9.1、strlen()函数
size_t strlen(const char *str);
计算字符串str的长度,直到“空结束字符”,但不包括“空结束字符”。
举例:
#include "string.h" //strlen()需要包含string.h头文件
void Test_strlen(void)
{
u8 length;
char buf[10]="123456";//声明char型数组buf[],并初始化
length=strlen(buf);//计算buf[]中的字符串长度
}
9.2、memset()函数
void *memset(void *str, int c, size_t n);
将c的值复制到str所指向的内存区域的“前n个字节”中。
size_t这是无符号整数类型,它是sizeof关键字的结果。
举例:
#include "string.h" //memset()需要包含string.h头文件
void Test_memset(void)
{
char buf[10]="123456789";
//声明char型数组buf[],并初始化
memset(buf,'\0',sizeof(buf));//将buf[]设置为0
}
#include "string.h" //memset()需要包含string.h头文件
void Test_memset(void)
{
float buf[5]={1.1,2.2,3.3,4.4,5.5};
//声明float型数组buf[],并初始化
memset(buf,'\0',sizeof(buf));//将buf[]设置为0
}
9.3、"string.h"中的复制函数
9.3.1、strcpy()函数
char *strcpy(char *dest, const char *src);
把src所指向的“字符串”复制到dest。
注意:如果目标数组dest不够大,而源字符串的长度又太长,会造成“内存溢出”。
9.3.1.1、strcpy应用举例
#include "string.h" //strcpy()和strlen()需要包含string.h头文件
void Test_strcpy(void)
{
char buf1[10]; //声明char型数组buf1[]
char buf2[10]="123456";//声明char型数组buf2[],并初始化
u8 length,size;
size=sizeof(buf1); //计算buf1[]的字节数
length=strlen(buf2); //计算buf2[]中的字符串长度
if(length<size)//如果"buf2[]中的字符串长度"小于数组buf1[]的字节数
{//可以使用strcpy()执行拷贝
strcpy(buf1,buf2); //将buf2[]中的字符串拷贝到buf1[]中
printf("%s\r\n",buf1);//串口输出buf1[]中的字符串
}
}
9.3.1.2、测试因strcpy执行拷贝引起的内存溢出
#include "string.h" //strcpy()需要包含string.h头文件
typedef struct{
char buf1[5]; //声明char型数组buf1[]
char buf2[5]; //声明char型数组buf2[]
char buf3[10];//声明char型数组buf3[]
}MemoryStruct;
MemoryStruct MEM={0};
void Test_MemoryOverflow(void)
{
MEM.buf3[0]='1';MEM.buf3[1]='2';MEM.buf3[2]='3';
MEM.buf3[3]='4';MEM.buf3[4]='5';MEM.buf3[5]='6';MEM.buf3[6]='\0';
strcpy(MEM.buf1,MEM.buf3); //将buf3[]中的字符串拷贝到buf1[]中
}
仿真后,发现目标数组buf1[]不够大,而buf3[]中的源字符串的长度太长,会造成“内存溢出”,结果见下图:

9.3.2、strncpy()函数
char *strncpy(char *dest, const char *src, size_t n);
把src所指向的“字符串”复制到dest,最多复制n个字符。当src的长度小于n时,dest的剩余部分将用“空字符”填充。
size_t这是无符号整数类型,它是sizeof关键字的结果。
注意:如果目标数组dest不够大,而源字符串的长度又太长,会造成“内存溢出”。
9.3.2.1、strncpy应用举例
#include "string.h" //memset(),strncpy()和strlen()需要包含string.h头文件
void Test_strncpy(void)
{
char buf1[10]="ABCDEFGHI";//声明char型数组buf1[],并初始化
char buf2[10]="123456";//声明char型数组buf2[],并初始化
u8 length,size;
size=sizeof(buf1); //计算buf1[]的字节数
length=strlen(buf2); //计算buf2[]中的字符串长度
if(length<size)//如果"buf2[]中的字符串长度"小于数组buf1[]的字节数
{//可以使用strncpy()执行拷贝
memset(buf1,'\0',sizeof(buf1));
//将buf1[]设置为0
//在使用strncpy之前,必须先将buf1[]清零,否则,字符串会缺少结束符;
strncpy(buf1,buf2,length); //将buf2[]中的前length个字符拷贝到buf1[]中
printf("%s\r\n",buf1);//串口输出buf1[]中的字符串
}
}
9.3.2.2、strncpy执行拷贝会引起的内存溢出
#include "string.h" //strncpy()需要包含string.h头文件
typedef struct{
char buf1[5]; //声明char型数组buf1[]
char buf2[5]; //声明char型数组buf2[]
char buf3[10];//声明char型数组buf3[]
}MemoryStruct;
MemoryStruct MEM={0};//声明MemoryStruct型结构变量MEM,并初始化为0
void Test_MemoryOverflow(void)
{
MEM.buf3[0]='1';MEM.buf3[1]='2';MEM.buf3[2]='3';
MEM.buf3[3]='4';MEM.buf3[4]='5';MEM.buf3[5]='6';MEM.buf3[6]='\0';
strncpy(MEM.buf1,MEM.buf3,7); //将buf3[]中的字符串拷贝到buf1[]中
}
仿真后,发现目标数组buf1[]不够大,而buf3[]中的源字符串的长度太长,会造成“内存溢出”,结果见下图:

9.3.3、memcpy()函数
void *memcpy(void *str1, const void *str2, size_t n);
将str2所指向的存储区的“前n个字节”复制到str1所指向的存储区。
size_t这是无符号整数类型,它是sizeof关键字的结果。
注意str1所指向的存储区必须至少有n个字节,否则,会引起内存溢出。
9.3.3.1、memcpy复制字节型数据
#include "string.h" //memcpy()需要包含string.h头文件
void Test_memcpy(void)
{
u8 buf1[10]={1,2,3,4,5,6,7,8,9,10};
//声明无符号8位数组buf1[],并初始化
u8 buf2[10]={1,2,3,4,5};
//声明无符号8位数组buf2[],并初始化
memset(buf1,'\0',sizeof(buf1));//将buf1[]的所有元素设置为0
memcpy(buf1,buf2,5); //将buf2[]中的前5个字节拷贝到buf1[]中
}
9.3.3.2、memcpy复制浮点数
#include "string.h" //memcpy()需要包含string.h头文件
void Test_memcpy(void)
{
float buf1[10]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.5};
//声明浮点数数组buf1[],并初始化
float buf2[10]={1.5,2.5,3.5,4.5,5.5};
//声明浮点数数组buf2[],并初始化
memset(buf1,'\0',sizeof(buf1));//将buf1[]的全部成员设置为0
memcpy(buf1,buf2,5*sizeof(float));
//将buf2[]中的前5个浮点数拷贝到buf1[]中
}
9.3.4、memmove()函数
void *memmove(void *str1, const void *str2, size_t n);
将str2所指向的存储区的“前n个字节”复制到str1所指向的存储区。
size_t这是无符号整数类型,它是sizeof关键字的结果。
memmove()允许“str1和str2所指向的存储区重叠”。通过检查地址关系,自动选择复制方向(从前往后或从后往前),确保数据复制的正确性。
注意:
1)、str1所指向的存储区必须至少有n个字节,否则,会引起内存溢出。
2)、当“str1和str2所指向的存储区重叠”时,memmove()要比memcpy()能执行正确的拷贝。如果“str1和str2所指向的存储区不重叠”,则memmove()和memcpy()拷贝的效果是一样的。
9.3.4.1、memmove复制浮点数
#include "string.h" //memmove()需要包含string.h头文件
void Test_memmove(void)
{
float buf1[10]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.5};
//声明浮点数数组buf1[],并初始化
float buf2[10]={1.5,2.5,3.5,4.5,5.5};//声明浮点数数组buf2[],并初始化
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
memmove(buf1,buf2,5*sizeof(float));
//将buf2[]中的前5个浮点数拷贝到buf1[]中
}
9.3.4.2、C语言中memmove和memcpy的区别
#include "string.h" //strcpy(),memcpy()和memmove()需要包含string.h头文件
void Test_memmove(void)
{
char buf[11];
//声明char型数组buf[]
memset(buf,'\0',sizeof(buf));//将buf[]设置为0
strcpy(buf,"abcdefg");
memcpy(&buf[1], &buf[0], 9);
//将"abcdefg\0\0"拷贝到起始的地址为&buf[1]中的存储单元中
printf("%s\r\n",&buf[1]);//串口输出"abcddfg",出现拷贝错误
memset(buf,'\0',sizeof(buf));//将buf[]设置为0
strcpy(buf,"abcdefg");
memmove(&buf[1], &buf[0],9);
//将"abcdefg\0\0"拷贝到起始的地址为&buf[1]中的存储单元中
printf("%s\r\n",&buf[1]);//串口输出"abcdefg",拷贝正确
//通过比较,我们发现dest>src,发现memcpy()有问题,而memmove()执行了正确的拷贝
memset(buf,'\0',sizeof(buf));//将buf[]设置为0
strcpy(buf,"abcdefg");
memcpy(&buf[0], &buf[1], 9);
//将"bcdefg\0\0\0"拷贝到起始的地址为&buf[1]中的存储单元中
printf("%s\r\n",&buf[0]);//串口输出"bcdefg",拷贝正确
memset(buf,'\0',sizeof(buf));//将buf[]设置为0
strcpy(buf,"abcdefg");
memmove(&buf[0], &buf[1],9);
//将"bcdefg\0\0\0"拷贝到起始的地址为&buf[1]中的存储单元中
printf("%s\r\n",&buf[0]);//串口输出"bcdefg"
//通过比较,我们发现dest<=src,发现memcpy()和memmove()均能执行正确的拷贝
}
9.4、"string.h"中的比较函数
9.4.1、memcmp()函数
int memcmp(const void *str1, const void *str2, size_t n));
将首地址为str1和str2的存储区中“前n个字节”进行比较。这里的n为“输入数组的字节数”。
size_t这是无符号整数类型,它是sizeof关键字的结果。
比较规则:若str1[0]=str2[0],则比较str1[1]和str2[1],直到str1[i]和str2[i]不等。如果str1[i]>str2[i],则返回值大于0,如果str1[i]<str2[i],则返回值小于0。如果全部相等,则返回值等于0。
memcmp()函数主要用来比较两个数据块是否一样。
9.4.1.1、memcmp()函数的返回值
#include "string.h" //strcpy()和memcmp()需要包含string.h头文件
void Test_memcmp(void)
{
char buf1[10];//声明char型数组buf1[]
char buf2[10];//声明char型数组buf2[]
int ret;//声明int型变量ret
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=memcmp(buf1,buf2,4);
//比较buf1[]和buf2[]的前4个字节
//若buf1[]和buf2[]相同,则ret=0
if(ret==0) printf("buf1[]=buf2[]\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a456");
ret=memcmp(buf1,buf2,4);//由于buf1[1]<buf2[1],则ret<0
if(ret<0) printf("buf1[1]=1<buf2[1]=4.\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a456");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=memcmp(buf1,buf2,4);//由于buf1[1]>buf2[1],则ret>0
if(ret>0) printf("buf1[1]=4>buf2[1]=1.\r\n");
}
9.4.1.2、使用memcmp()比较两个浮点数数组是否相同
#include "string.h" //memcmp()需要包含string.h头文件
void Test_memcmp(void)
{
float buf1[3]={1.1,2.2,3.3};//声明float型数组buf1[]
float buf2[3]={1.1,2.2,3.3};//声明float型数组buf2[]
int ret;//声明int型变量ret
ret=memcmp(buf1,buf2,3*sizeof(float));
//比较buf1[]和buf2[]的前3个浮点数是否相同
if(ret==0) printf("buf1[]=buf2[]\r\n");
}
9.4.2、strcmp()函数
int strcmp(const char *str1, const char *str2);
将首地址为str1和str2的存储区中“字符串”进行比较。
比较规则:若str1[0]=str2[0],则比较str1[1]和str2[1],直到str1[i]和str2[i]不等。如果str1[i]>str2[i],则返回值大于0,如果str1[i]<str2[i],则返回值小于0。如果全部相等,则返回值等于0。
strcmp()函数主要用来比较两个字符串是否相同。
9.4.2.1、strcmp()函数的返回值
#include "string.h" //strcpy()和strcmp()需要包含string.h头文件
void Test_strcmp(void)
{
char buf1[10];//声明char型数组buf1[]
char buf2[10];//声明char型数组buf2[]
int ret;//声明int型变量ret
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=strcmp(buf1,buf2);
//若buf1[]和buf2[]相同,则ret=0
if(ret==0) printf("buf1[]=buf2[]\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a456");
ret=strcmp(buf1,buf2);//由于buf1[1]<buf2[1],则ret<0
if(ret<0) printf("buf1[1]=1<buf2[1]=4.\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a456");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=strcmp(buf1,buf2);//由于buf1[1]>buf2[1],则ret>0
if(ret>0) printf("buf1[1]=4>buf2[1]=1.\r\n");
}
9.4.3、strcoll()函数
打开“D:\Keil_v5\ARM\ARMCC\include\locale.h”
#define LC_COLLATE 1
//选择C语言环境的归类类别
/*影响strcoll()函数的行为,affects the behaviour of the strcoll function */
注意:在MDK-ARM中,strcoll()和strcmp()功能一样。
int strcoll(const char *str1, const char *str2);
将首地址为str1和str2的存储区中“字符串”进行比较。返回值取决于LC_COLLATE的设置。
比较规则:若str1[0]=str2[0],则比较str1[1]和str2[1],直到str1[i]和str2[i]不等。如果str1[i]>str2[i],则返回值大于0,如果str1[i]<str2[i],则返回值小于0。如果全部相等,则返回值等于0。
#include "string.h" //strcpy()和strcoll()需要包含string.h头文件
#include "locale.h" //在"locale.h"定义LC_COLLATE为1
void Test_strcoll(void)
{
char buf1[10];//声明char型数组buf1[]
char buf2[10];//声明char型数组buf2[]
int ret;//声明int型变量ret
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=strcoll(buf1,buf2);
//若buf1[]和buf2[]相同,则ret=0
if(ret==0) printf("buf1[]=buf2[]\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a456");
ret=strcoll(buf1,buf2);//由于buf1[1]<buf2[1],则ret<0
if(ret<0) printf("buf1[1]=1<buf2[1]=4.\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a456");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=strcoll(buf1,buf2);//由于buf1[1]>buf2[1],则ret>0
if(ret>0) printf("buf1[1]=4>buf2[1]=1.\r\n");
}
9.4.4、strncmp()函数
int strncmp(const char *str1, const char *str2, size_t n);
将首地址为str1和str2的存储区中“前n个字符”进行比较。这里的n通常为“输入数组的字节数”。
size_t这是无符号整数类型,它是sizeof关键字的结果。
比较规则:若str1[0]=str2[0],则比较str1[1]和str2[1],直到str1[i]和str2[i]不等。如果str1[i]>str2[i],则返回值大于0,如果str1[i]<str2[i],则返回值小于0。如果全部相等,则返回值等于0。
strncmp()函数主要用来比较两个字符串的“前n个字符”是否一样。
9.4.4.1、strncmp()函数的返回值
#include "string.h" //strcpy()和strncmp()需要包含string.h头文件
void Test_strncmp(void)
{
char buf1[10];//声明char型数组buf1[]
char buf2[10];//声明char型数组buf2[]
int ret;//声明int型变量ret
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=strncmp(buf1,buf2,4);
//比较buf1[]和buf2[]的前4个字符
//若buf1[]和buf2[]相同,则ret=0
if(ret==0) printf("buf1[]=buf2[]\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a123");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a456");
ret=strncmp(buf1,buf2,4);//由于buf1[1]<buf2[1],则ret<0
if(ret<0) printf("buf1[1]=1<buf2[1]=4.\r\n");
memset(buf1,'\0',sizeof(buf1));//将buf1[]设置为0
strcpy(buf1,"a456");
memset(buf2,'\0',sizeof(buf2));//将buf2[]设置为0
strcpy(buf2,"a123");
ret=strncmp(buf1,buf2,4);//由于buf1[1]>buf2[1],则ret>0
if(ret>0) printf("buf1[1]=4>buf2[1]=1.\r\n");
}
9.5、"string.h"中的搜索第1次出现的值
9.5.1、memchr()函数
void *memchr(const void *str, int c, size_t n);
在str[]的“前n个字节”中,搜索首次出现c的值。这里的n为“输入数组的字节数”。
size_t这是无符号整数类型,它是sizeof关键字的结果。
9.5.1.1、memchr()函数的返回值
#include "string.h" //memchr()需要包含string.h头文件
void Test_memchr(void)
{
u8 buf[5]={1,2,3,4,5};
//声明u8型数组buf[],并初始化
u8 *p;
p=memchr(buf,4,sizeof(buf));
//在buf[]中查找
//若搜索到4,则返回4在buf[]中的地址
if(p) printf("Find 4 in buf[]\r\n");
p=NULL;//赋空指针
}
#include "string.h" //memchr()需要包含string.h头文件
void Test_memchr1(void)
{
int16_t buf[5]={10000,10002,10003,-44,10005};
//声明int16_t型数组buf[],并初始化
int16_t *p;
p=memchr(buf,-44,sizeof(buf));
//在buf[]中查找-44
//若搜索到-44,则返回-44在buf[]中的地址
if(p) printf("Find -44 in buf[]\r\n");
p=NULL;//赋空指针
}
9.5.2、strchr()函数
char *strchr(const char *str, int c);
在首地址为str的字符串中,搜索首次出现c的值。
#include "string.h" //strchr()需要包含string.h头文件
void Test_strchr(void)
{
char buf[5]={'1','2','3','4','\0'};
//声明char型数组buf[],并初始化
char *p;//声明char型指针变量p;
p=strchr(buf,'3');
//在buf[]中查找"字符3"
//若搜索到"字符3",则返回"字符3"在buf[]中的地址
if(p) printf("Find '3' in buf[]\r\n");
p=NULL;//赋空指针
}
9.6、自建的strnchr()函数
memchr()函数和strchr()函数均可用来在字符串中查找“首次出现的某个字符”,但我们通常会查找“出现第几次同样的字符”。因此,我自己写了这个搜索字符的函数。
//涵数功能:在s1[]中搜索第n次出现的字符c,并将其地址返回;
char *strnchr( char *s1, int c, uint16_t n)
{ char *last;
char *current;
last = NULL;
//只有第 2 个字符串并不为空时才进行查找,如果 s2 为空,返回 NULL
if(c != '\0')
{ //查找 c的值 在 s1 中第一次出现的位置
current = strchr( s1, c);
//每次找到字符串时,让指针指向它的起始位置.然后查找该字符串下一个匹配位置
while( (current != NULL)&&(n>0) )
{ last = current; //记录c的值所在的位置;
n--; //每搜索到一次,自减一;
current = strchr(last+1, c);
}
}
if(n>0) last = NULL;
return last;
}
void Test_strnchr(void)
{
char buf[5]="ABAB";
char *p;
p=strnchr(buf,'A',2);
//在buf[]中搜索第2次出现的字符'A'
if(p) printf("Find 'A' in buf[]\r\n");
p=NULL;//赋空指针
}
9.7、strrchr()函数
char *strrchr(const char *str, int c);
在首地址为str的字符串中,搜索“最后一次出现c的值”。
#include "string.h" //strrchr()需要包含string.h头文件
void Test_strrchr(void)
{
char buf[5]={'1','3','3','4','\0'};
//声明char型数组buf[],并初始化
char *p;//声明char型指针变量p;
p=strrchr(buf,'3');
//在buf[]中查找"最后一次出现的字符3"
//若搜索到"最后一次出现的字符3",则返回"最后一次出现的字符3"在buf[]中的地址
if(p) printf("Find '3' in buf[]\r\n");
p=NULL;//赋空指针
}
9.8、strstr()和strpbrk()函数
9.8.1、strstr()函数
char *strstr(const char *src, const char *str);
在首地址为src的字符串中,搜索首次出现“str所指向的字符串”,但不包含“字符串结束符'\0'”。主要是用来搜索第1次出现的字符串。
#include "string.h" //strstr()需要包含string.h头文件
void Test_strstr(void)
{
char buf[5]={'1','2','3','4','\0'};
//声明char型数组buf[],并初始化
char *p;//声明char型指针变量p;
p=strstr(buf,"23");
//在buf[]中查找"字符串23",但不包含字符串结束符'\0'
//若搜索到"字符串23",则返回"字符串23"在buf[]中的地址
if(p) printf("Find \"23\" in buf[]\r\n");
p=NULL;//赋空指针
}
9.8.2、strpbrk函数
char *strpbrk(const char *src, const char *str);
在首地址为src的字符串中,搜索首次出现“str中的字符”,但不包含“字符串结束符'\0'”。
主要是用来搜索第1次出现的字符串中的字符。
#include "string.h" //strpbrk()需要包含string.h头文件
void Test_strpbrk(void)
{
char buf[5]={'1','2','3','4','\0'};
//声明char型数组buf[],并初始化
char *p;//声明char型指针变量p;
p=strpbrk(buf,"24");
//在buf[]中查找首次出现"字符2和字符4",但不包含字符串结束符'\0'
//若搜索到"字符2或字符4",则返回"字符2或字符4"在buf[]中的地址
if(p) printf("Find '2' or '4' in buf[]\r\n");
p=NULL;//赋空指针
}

9.9、自建的strnstr()函数
#include "string.h" //strstr()需要包含string.h头文件
//涵数功能:在s1[]中搜索第n次出现的字符串,匹配字符串在s2[]中;
char *strnstr(char *s1, char *s2,uint16_t n)
{ char *last;
char *current;
last = NULL;
//只有第 2 个字符串并不为空时才进行查找,如果 s2 为空,返回 NULL
if(*s2 != '\0')
{ //查找 s2 在 s1 中第一次出现的位置
current = strstr(s1, s2);
//每次找到字符串时,让指针指向它的起始位置.然后查找该字符串下一个匹配位置
while( (current != NULL)&&(n>0) )
{ last = current;
n--; //每搜索到一次,自减一;
current = strstr(last+1, s2);
}
}
if(n>0) last = NULL;
return last;
}
void Test_strnstr(void)
{
char buf[5]="ABAB";//声明char型数组buf[],并初始化
char *p;
p=strnstr(buf,"AB",2);
//在buf[]中搜索第2次出现的字符串"AB"
if(p) printf("Find \"AB\" in buf[]\r\n");
p=NULL;//赋空指针
}
9.10、在“已知字符串的尾部”追加“加字符串”
9.10.1、strcat()函数
char *strcat(char *dest, const char *src);
将“src所指向的字符串”追加到“dest所指向的字符串的结尾”。
#include "string.h" //strcat()需要包含string.h头文件
void Test_strcat(void)
{
char buf[10]="ABCD";//声明char型数组buf[],并初始化
strcat(buf,"EF");
//将"EF字符串”追加"buf所指向的字符串的结尾"
//得到buf[10]="ABCDEF";
printf("%s\r\n",buf);
}
9.10.2、strncat()函数
char *strncat(char *dest, const char *src, size_t n);
将“src所指向的字符串”追加“dest所指向的字符串的结尾”,直到n字符长度为止。
#include "string.h" //strcpy()和strncat()需要包含string.h头文件
void Test_strncat(void)
{
char buf[10];//声明char型数组buf[]
strcpy(buf,"ABCD"); //将"ABCD"拷贝到buf[]中
strncat(buf,"EF",4);
//将"EF字符串”追加"buf所指向的字符串的结尾",最多添加4个字符;
//得到buf[10]="ABCDEF";
printf("%s\r\n",buf);
strcpy(buf,"ABCD"); //将"ABCD"拷贝到buf[]中
strncat(buf,"EFGH",3);
//将"EF字符串”追加"buf所指向的字符串的结尾",最多添加3个字符;
//得到buf[10]="ABCDEFG";
printf("%s\r\n",buf);
}
9.11、strcspn()和strspn()函数
9.11.1、strcspn()函数
size_t strcspn(const char *str1, const char *str2);
从str1所指向的字符串的开头检索,查找多少个字符不含有“str2字符串中的字符”。
#include "string.h" //strcpy()和strcspn()需要包含string.h头文件
void Test_strcspn(void)
{
char buf[10];//声明char型数组buf[]
u8 ret;//声明u8型变量
strcpy(buf,"ABCD\r\n"); //将"ABCD\r\n"拷贝到buf[]中
ret=strcspn(buf,"\r\n");
//从buf所指向的字符串的开头检索,查找多少个字符不含有"\r\n"中的字符。
//在"ABCD\r\n"中,最开始的4个字符不含有"\r\n"中的字符,因此ret=4
printf("ret=%u\r\n",ret);
strcpy(buf,"AB\rCD\r\n"); //将"AB\rCD\r\n"拷贝到buf[]中
ret=strcspn(buf,"\r\n");
//从buf所指向的字符串的开头检索,查找多少个字符不含有"\r\n"中的字符。
//在"AB\rCD\r\n"中,最开始的2个字符不含有"\r\n"中的字符,因此ret=2
printf("ret=%u\r\n",ret);
}
9.11.2、strspn()函数
size_t strspn(const char *str1, const char *str2);
从str1所指向的字符串的开头检索,查找多少个字符含有“str2字符串”。
#include "string.h" //strcpy()和strspn()需要包含string.h头文件
void Test_strspn(void)
{
char buf[10];//声明char型数组buf[]
u8 ret;//声明u8型变量
strcpy(buf,"ABCD"); //将"ABCD"拷贝到buf[]中
ret=strspn(buf,"AB");
//从buf所指向的字符串的开头检索,查找多少个字符含有"AB"中的字符。
//在"ABCD"中,最开始的4个字符含有"AB"中的字符,因此ret=2
printf("ret=%u\r\n",ret);
strcpy(buf,"ABCD"); //将"ABCD"拷贝到buf[]中
ret=strspn(buf,"BC");
//从buf所指向的字符串的开头检索,查找多少个字符含有"BC"中的字符。
//在"ABCD"中,最开始的字符不是'B',因此ret=0
printf("ret=%u\r\n",ret);
}
9.12、strtok()函数
char *strtok(char *str, const char *delim);
根据“delim所指向的字符串(分割字符串)”对“str为首地址的字符串”进行肢解,使其变成若干个子字符串。
在第一次调用时,传入“delim所指向的字符串(分割字符串)”,后续调用时,传入NULL,表示继续使用“delim所指向的字符串(分割字符串)”对“str为首地址的字符串”进行分割。
#include "string.h" //strtok()和strcpy()需要包含string.h头文件
void Test_strtok(void)
{
char buf1[20];//声明char型数组buf1[]
char *pToken;//声明char型指针变量pToken;
char buf2[20];//声明char型数组buf2[]
strcpy(buf1,"\r\nOK1\r\nOK2\r\nOK3");
pToken=strtok(buf1,"\r\n");
//在第一次调用时,传入要分割的字符串"\r\n"
//后续调用时,传入NULL,表示继续使用"\r\n"进行分割。
//在buf[]中查找首次出现分割字符串"\r\n",但不包含字符串结束符'\0';
//若搜索到"\r\n",则返回"\r\n"在buf[]中的下一个字符的地址;
while(pToken!=NULL)
{
strcpy(buf2,pToken);//拷贝"分割得到的子字符串"
printf("%s\r\n",buf2);//串口输出"分割得到的子字符串"
pToken=strtok(NULL,"\r\n");
//传入NULL,表示继续使用"\r\n"对buf[]进行分割。
}
pToken=NULL;//赋空指针
}
9.13、strxfrm()函数
size_t strxfrm(char *dest, const char *src, size_t n);
根据程序当前的区域选项中的LC_COLLATE来转换字符串src的前n个字符,并把它们放置在字符串dest中。返回src源字符串的长度。很少用到,了解即可。
#include "string.h" //strcpy()和strxfrm()需要包含string.h头文件
typedef struct{
char buf1[5]; //声明char型数组buf1[]
char buf2[5]; //声明char型数组buf2[]
char buf3[10];//声明char型数组buf3[]
}MemoryStruct;
MemoryStruct MEM;//声明MemoryStruct型结构变量MEM
void Test_strxfrm(void)
{
u8 Copylength;
u8 len;
memset(MEM.buf1,'\0',sizeof(MEM.buf1));
memset(MEM.buf3,'\0',sizeof(MEM.buf3));
strcpy(MEM.buf3,"ABCD");
Copylength=strlen(MEM.buf3);
if(sizeof(MEM.buf1)>=Copylength)
{//防止内存溢出
len=strxfrm(MEM.buf1,MEM.buf3,Copylength);
//将MEM.buf3[]的前4个字符拷贝到MEM.buf1[]中,
//并返回MEM.buf3[]中源字符串的长度。
}
printf("len=%u\r\n",len);
}
void Test_strxfrm_MemoryOverflow(void)
{
u8 Copylength;
u8 len;
memset(MEM.buf1,0,sizeof(MEM.buf1));
memset(MEM.buf2,'F',sizeof(MEM.buf2));
strcpy(MEM.buf3,"ABCDEFGHI");
Copylength=strlen(MEM.buf3);//Copylength=9
len=strxfrm(MEM.buf1,MEM.buf3,Copylength);
//将MEM.buf3[]的前9个字符拷贝到MEM.buf1[]中
//并返回MEM.buf3[]中源字符串的长度。
printf("len=%u\r\n",len);
}

更多推荐


所有评论(0)