字符串操作函数

1.memset

memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。

函数介绍

#include<string.h>
void *memset(void *s, int ch, size_t n);

解释:将s中当前位置后面n个字节用ch替换;
作用:在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法 。

函数原型:

extern void *memset(void *buffer, int c, int count)
buffer:数组或者指针
c:是赋给buffer的值
count:是buffer的长度

1.函数常用于内存空间初始化
2.用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化
3.可以方便的清空一个结构类型的变量或数组

2.strncat

注.(得到的新串后面自动加上NULL字符)

1.函数原型

char * strncat(char *str1,const *char *str2,size_t_n);

2.作用:用于连接字符串,该函数要求指明在原字符串末尾附加的目标字符串的长度。

(1)如果str2的字符数大于n,那么该函数只将str2的前n个字符附加在str1末尾;(2)如果str2的字符数小于n,那么该函数会将str2 的所有字符附加在str1末尾。无论哪种情况,都会在新字符串的末尾添加空字符,必须为str1分配足够的空间以存储新的字符串。
strncat()函数返回指向str1的指针。

#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[])
{
char dest[10]=“demo”;
char src[20]=“strncat”;
strncat(dest,src,7);
printf("%s\n",dest);
return 0;
}

在这里插入图片描述

3.strncpy

注.strncpy不拷贝’\0’

strcpy是个不安全函数,需考虑str前者空间大小,如果p指向的串太大则会造成程序崩溃。

1.函数原型

char *strncpy(char *dest, char *src, size_t num);

#include<string.h>
#include<stdio.h>
int main()
{
        char str[4]={0};
        const char *p="a\0bcdefg";
        strncpy(str,p,sizeof(str)-1);
        printf("%s\n",str);
        return 0;
}
~  输出结果为a

总结: 1.先定义并初始化 char str[MAX + 1] = {0};
如果程序中间需要再往str中拷贝串,一定要用memset清零。拷贝范式:strncpy(str, p, sizeof(str) - 1);
2.strcnpy拷贝的是字符,不拷贝串,所以最后一个\0不拷贝(若在中间遇到\0则后面不拷贝),拷贝的时候需要对串进行清零处理。
3.strncpy拷贝时,可能会导致截断,但程序不会崩溃。
4.strcnpy的原型,也并不一定 拷贝num个字符也有特殊情况。

#include<stdio.h>
int main(int argc,char *argv[])
{
	char str[4]={'x','y','z','b'};
	char *p="a\0bcdeadg";
	strcnpy(str,p,sizeof(str)-1);
	printf("%c\n",(char)str[0]);	//'a'
	printf("%d\n",(int)str[1]);	    //'\0'
	printf("%d\n",(int)str[2]);	    //'\0'
	printf("%c\n",(char)str[3]);	//'b'
	return 0;
}

5.关于strncpy,要防止内存重叠
内存重叠问题参考博文

4.strncasecmp

1.定义和用法
strncasecmp() 函数比较两个字符串(不区分大小写)。
strncasecmp() 是二进制安全的,且不区分大小写。
strcasecmp() 没有 length 参数。

2.语法
strncasecmp((const char *str1, const char *str2,size_t n);
str1:需要比较的第一个字符串
str2:需要比较的第二个字符串
n:比较参数str1和str2字符串前n个字符,比较时自动忽略大小写的差异。
返回值:
如果两个字符串相同返回值为0
如果str1>str2返回值为>0
如果str1<str2返回值为<0

#include<stdio.h>
#include<string.h>
int main(int argc,char *argv[])
{
        char *a="aBCDEFG";
        char *b="aBCDHSD";
        printf("%d\n",strncasecmp(a,b,4));  //0 
        return 0;
}

5.snprintf

1.函数原型

int snprintf(char *str, size_t size, const char *format, ...);

2.函数参数
str:目标字符串;size:拷贝字节数(Bytes); format:源字符串; …格式

最多从源字符串format中拷贝size字节的内容(含字符串结尾标志’\0’)到目标字符串
3.返回值

<1>成功返回源字符串的长度(strlen, 不含’\0’)
<2>失败返回负值

#include<stdio.h>
int main(int argc,char *argv[])
{
	char buf[12]={0};
	size_t t;
	t=snprintf(buf,sizeof(buf),"%d",1234567891);	//t=10,buf:1234567891 \0
	printf("size=%ld,text:%s\n",t,buf);
	return 0;
}

(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符(’\0’);

(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符(’\0’),返回值为欲写入的字符串长度。

文章二:snprintf/_snprintf 在不同平台间函数差异

不同平台函数差异

6.strtok_r

1.函数原型:

#include <string.h>
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);

2.函数参数:

char *str是被分割字符串,第一次调用函数strtok_r时此指针一定不能为空,连续分割同一个字符串时,第一次调用之后的调用需将str设置为NULL。
const char *delim是分隔符,也是个字符串指针。
char **saveptr是一个供内部使用的指针,用于保存上次分割剩下的字串。

3.返回值
返回值是个指针,用于返回从被分割字符串中得到的第一个目标子串。
注意:虽然函数strtok_r可以将一个字符串进行分割,但是每次分割只能得到第一个被分割的字串

4.参考博文
strtok与strtok_r实现原理

strtok_r实际上就是将strtok内部隐式保存的this指针,以参数的形式与函数外部进行交互。由调用者进行传递、保存甚至是修改。需要调用者在连续切分相同源字符串时,除了将str参数赋值为NULL,还要传递上次切分时保存下的saveptr。

#include<stdio.h>
#include<string.h>

#define INFO_MAX_SZ     1024

int main(int argc,char *argv[])
{
        int in=0;
        int i=0;
        char name[INFO_MAX_SZ]="FIRST male 22,SECOND males 23,Thrid males 24";
        char *p[20];
        char *buf=name;
        char *outer_ptr=NULL;
        char *inner_ptr=NULL;
        while((p[in]=strtok_r(buf,",",&outer_ptr))!=NULL)
        {
                buf=p[in];
                while((p[in]=strtok_r(buf," ",&inner_ptr))!=NULL)
                {
                        in++;
                        buf=NULL;
                }

                buf=NULL;
        }
        printf("we hava %d string\n",in);
        for(i=0;i<in;i++)
        {
                printf("%s\n",p[i]);
        }
        return 0;
}

outer_ptr和inner_ptr。outer_ptr用于标记每个人的提取位置,即外循环;inner_ptr用于标记每个人内部每项信息的提取位置,即内循环。

<1>第一次外循环,outer_ptr忽略,分割符 ",“被修改为 ‘ \0 ’;对整个源串提取,outer_ptr返回指向S。
<2>第一次内循环,innner_ptr忽略,对第一次外循环的提取结果“FIRST male 22”进行提取,提取出"FIRST”。分割符 " “被修改为 ’ \0 ';inner_ptr返回指向m。
<3>第二次内循环,传递第一次内循环返回的inner_ptr,第一个参数为NULL;从inner_ptr指向位置” m “进行提取,提取出” male “。分隔符” “被修改为’\0’;inner_ptr返回指向2;
<4>第三次内循环,传递第二次内循环返回的inner_ptr,第一个参数为NULL;从inner_ptr指向位置” 2 "进行提取,提取出“ 22 ”。因为没有找到“ ”,
inner_ptr返回指向22后面的 ’ \0 ’ ;
<5>第四次内循环,传递第三次内循环返回的inner_ptr,第一个参数为NULL;因为inner_ptr指向的位置为’\0’;无法提取,返回空值结束内循环。
<6>第二次外循环,传递第一次外循环返回的outer_ptr,第一个参数为NULL;从outer_ptr返回的位置S进行提取,提取出“SECOND males 23”,将分割符“,”修改为’\0’;outer_ptr返回指向T;
…以此类推。

7.sccanf

#include<stdio.h>

int main(int argc,char *argv[])
{
        char *string;
        int ret;
        char protocol[255];
        char domain[255];
        char port[255];
        char path[255];
        char ip[255];

        char username[255];
        char password[255];
/*
        string="http://www.grandstream.com:8088/cgi?a=fangjia&b=sss";

        ret=sscanf(string,"%[^:]://%[^:]:%[^/]/%[^?]",protocol,domain,port,path);

        printf("%s\n",protocol);
        printf("%s\n",domain);
        printf("%s\n",port);
        printf("%s\n",path);
*/
/*
        string="sips:Alice:s1ptest@grandstream.cn:5060";
        ret=sscanf(string,"%[^:]:%[^:]:%[^@]@%[^:]:%s",protocol,username,password,domain,port);
        
        printf("%s\n",protocol);
        printf("%s\n",username);
        printf("%s\n",password);
        printf("%s\n",domain);
        printf("%s\n",port);
*/

        string="ftp://[8000::2]:9999/filename.tgz";
        ret=sscanf(string,"%[^:]://[%[^]]]:%[^/]/%s",protocol,ip,port,domain);

        printf("%s\n",protocol);
        printf("%s\n",ip);
        printf("%s\n",port);
        printf("%s\n",domain);

        return 0;
}
                                                                                                        

demo01:

http
www.grandstream.com
8088
cgi

demo02:

sips
Alice
s1ptest
grandstream.cn
5060

demo03:

ftp
8000::2
9999
filename.tgz

参考博文:

关于sscanf的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值