1、C语言中没有提供字符串替换函数,网上能找到的类似函数也只是能替换一个,不能替换全部,工作中却常常要用到这个功能,故实现一个函数。该函数所使用到的相关函数均是自己实现,没有调用库函数。
大石桥ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联建站的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
2、函数代码如下:
/*descript:replace str,返回一个替换以后的字符串,用完之后要free()
success:return 1
error:return 0
BUG:"select * from tab where id=':a' and name =':aa'",this is not support,this function is just simple str_replace ,not support all SQL language
*/
char *replacestr(char *strbuf, char *sstr, char *dstr)
{ char *p,*p1;
int len;
if ((strbuf == NULL)||(sstr == NULL)||(dstr == NULL))
return NULL;
p = strstr(strbuf, sstr); //返回字符串第一次出现的地址,否则返回NULL
if (p == NULL) /*not found*/
return NULL;
len = strlen(strbuf) + strlen(dstr) - strlen(sstr);
p1 = malloc(len);
bzero(p1, len);
strncpy(p1, strbuf, p-strbuf);
strcat(p1, dstr);
p += strlen(sstr);
strcat(p1, p);
return p1;
}
strncpy这个库函数的实现就是strncpy(目标, 源, 字符个数);第3个参数用于防止越界的;返回值是char *类型;
strncpy(file_name, buffer,strlen(buffer) FILE_NAME_MAX_SIZE ?FILE_NAME_MAX_SIZE : strlen(buffer));
根据变量命名规则,估计大概的意思就是从输入(buffer)中获取文件名;如果这个文件名的长度大于FILE_NAME_MAX_SIZE,那么截取FILE_NAME_MAX_SIZE个字符作为文件名;否则buffer中的字符全是文件名
C语言数组和整型数组清空方法,示例:
1、整数数组清零
函数:void bzero(void *s, int n)
头文件: #include string.h
功能说明:将字符串s的前n个字符置为0,一般n取sizeof(s),将整块空间清零;
举例:char str[10]; bzero(str, sizeof(str)); 也可以将整个结构体清零;
2、数组清空
使用时间:94s
for( k = 0 ; k 10000 ; k++ )
for( i = 0 ; iMAX; i++ )
for( j = 0;j MAX; j++ )
a[i][j] = 0;
扩展资料
C语言结构体初始化
1、定义:
struct InitMember
{
int first;
double second;
char* third;
float four;
};
2、定义时赋值:
struct InitMember test = {-10,3.141590,"method one",0.25};
bzero
原型:extern void bzero(void *s, int n);用法:#include string.h功能:置字节字符串s的前n个字节为零且包括‘\0’。说明:bzero无返回值,并且使用strings.h头文件,strings.h曾经是posix标准的一部分,但是在POSIX.1-2001标准里面,这些函数被标记为了遗留函数而不推荐使用。在POSIX.1-2008标准里已经没有这些函数了。推荐使用memset替代bzero。
void *memset(void *s, int ch, size_t n);函数解释:将s中前n个字节替换为ch并返回s;memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。常见的三种错误第一: 搞反了ch 和 n的位置.一定要记住 如果要把一个char a[20]清零, 一定是 memset(a, 0, 20)而不是 memset(a, 20, 0)第二: 过度使用memset, 我想这些程序员可能有某种心理阴影, 他们惧怕未经初始化的内存, 所以他们会写出这样的代码:char buffer[20];memset(buffer, 0, sizeof((char)*20));strcpy(buffer, "123");这里的memset是多余的. 因为这块内存马上就被覆盖了, 清零没有意义.第三: 其实这个错误严格来讲不能算用错memset, 但是它经常在使用memset的场合出现
关于字符数组的初始化,在项目的压力测试中,发现性能明显下降,变怀疑在程序中的若干临时字符数组的初始化(使用bzero)身上。于是修改为首个字符置零的方式而非全部置零的方式初始化,响应得到明显的提升。原来在mp3检索的每一条结果都要进行bzero对临时数组初始化,每一个请求需要30次的bzero对临时数组的置零。于是想到了,在非必要的情况下,只对临时数组的第一个(或前几个)字符置零的初始化方式对比与使用bzero的话,能够明显提高性能。
一般使用下面两个函数。
bzero
原型:extern void bzero(void *s, int n);
参数说明:s 要置零的数据的起始地址; n 要置零的数据字节个数。
用法:#include string.h
功能:置字节字符串s的前n个字节为零且包括‘\0’。
memset
原型:void *memset(void *s, int ch, size_t n);
参数说明:s 要置零的数据的起始地址; ch要替换的字符; n 要置零的数据字节个数。
用法:#include string.h
功能:将s中的前n个字节用ch替换并且返回s。
void __bzero (void *s, size_t len);
/*
将s的前len字节设为0
思路:先对齐到4的倍数的地址上,对前面的几B直接赋。然后,每次赋个32B,剩余凑不够32B的,
每次赋4B,剩余凑不够4B的,直接赋
*/
void __bzero (void *s, size_t len)
{
long int dstp = (long int) s;
const op_t zero = 0;
if (len = 8)
{
size_t xlen;
// 处理前面的几B,直到地址为4的倍数,然后可以每次4B
// 这样做的原因与结构体对齐的原因一样,是为提高读写数据的效率
// 由于len = 8 ,OPSIZ=4,所以不必担心len==0
while (dstp % OPSIZ != 0) // #define op_t unsigned long int
// #define OPSIZ (sizeof(op_t))
// IA-32下是32
{
((byte *) dstp)[0] = 0;
dstp += 1;
len -= 1;
}
// 下面是典型的循环展开以提高效率,每次32B
// 若每次赋一个4B,程序会由于跳转太多而打断cpu流水线,降低效率
//
// 关键字:Duff's Device
xlen = len / (OPSIZ * 8);
while (xlen != 0)
{
((op_t *) dstp)[0] = zero;
((op_t *) dstp)[1] = zero;
((op_t *) dstp)[2] = zero;
((op_t *) dstp)[3] = zero;
((op_t *) dstp)[4] = zero;
((op_t *) dstp)[5] = zero;
((op_t *) dstp)[6] = zero;
((op_t *) dstp)[7] = zero;
dstp += 8 * OPSIZ;
xlen -= 1;
}
len %= OPSIZ * 8; // 剩余的凑不足8 op_t 的
xlen = len / OPSIZ;
while (xlen != 0) // 每次填4B
{
((op_t *) dstp)[0] = zero;
dstp += OPSIZ;
xlen -= 1;
}
len %= OPSIZ;
}
while (len != 0) // 剩余不够4B的,直接赋值
{
((byte *) dstp)[0] = 0;
dstp += 1;
len -= 1;
}
}