"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()允许str1str2所指向的存储区重叠”。通过检查地址关系,自动选择复制方向(从前往后或从后往前),确保数据复制的正确性。

注意:

1)、str1所指向的存储区必须至少有n个字节,否则,会引起内存溢出。

2)、当“str1str2所指向的存储区重叠”时,memmove()要比memcpy()能执行正确的拷贝。如果“str1str2所指向的存储区不重叠”,则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));

将首地址为str1str2的存储区中“前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);

将首地址为str1str2的存储区中“字符串进行比较。

比较规则:若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);

将首地址为str1str2的存储区中“字符串进行比较。返回值取决于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);

将首地址为str1str2的存储区中“前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);

}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐