字符串操作

总结下字符串操作函数,然后自己再实现下,就这样。

1.初始化字符串

#include <string.h>

void *memset(void *s, int c, size_t n);

返回值:和s的指向相同

说明: memset函数把s所指的内存地址开始的n个字节都填充为c的值。通常c的值为0,把一块内存区清零。例如定义char buf[10];,如果它是全局变量或静态变量,则自动初始化为0(位于.bss段),如果它是函数的局部变量,则初值不确定,可以用memset(buf, 0, 10)清零,由malloc分配的内存初值也是不确定的,也可以用memset清零。

具体的实现:

void * memset(void* buffer, int c, int count)
{
	char* pvTo=(char*)buffer;
	assert(buffer != NULL);
	while(count-->0)
		*pvTo++=(char)c;
	return buffer;
}


 

2,求字符串的长度

#include <string.h>

size_t strlen(const char *s);

返回值:字符串的长度

说明:strlen函数返回s所指的字符串的长度。该函数从s所指的第一个字符开始找'\0'字符,一旦找到就返回,返回的长度不包括'\0'字符在内。例如定义char buf[]= "hello";,则strlen(buf)的值是5,但要注意,如果定义char buf[5] = "hello";,则调用strlen(buf)是危险的,会造成数组访问越界。

具体实现代码:

size_t strlen(const char* str) 
{
	assert(str!=NULL);
	int len = 0;
	while (*str!='\0') /**< '\0', stop */
	{		
		str++;
		len++ ;
	}
	return len;
}

 

3.字符串拷贝

#include<string.h>

void *memcpy(void *dest, const void *src, size_t n);

void *memmove(void *dest, const void *src, size_t n);

char *strcpy(char *dest,const char *src);

返回值:dest指向哪,返回的指针就指向哪

memcpy函数从src所指的内存地址拷贝n个字节到dest所指的内存地址,和strncpy不同,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。这里的命名规律是,以str开头的函数处理以'\0'结尾的字符串,而以mem开头的函数则不关心'\0'字符,或者说这些函数并不把参数当字符串看待,因此参数的指针类型是void *而非char *

memmove也是从src所指的内存地址拷贝n个字节到dest所指的内存地址,虽然叫move但其实也是拷贝而非移动。但是和memcpy有一点不同,memcpy的两个参数srcdest所指的内存区间如果重叠则无法保证正确拷贝,而memmove却可以正确拷贝。假设定义了一个数组char buf[20] = "hello world\n";,如果想把其中的字符串往后移动一个字节(变成"hhello world\n"),调用memcpy(buf + 1, buf, 13)是无法保证正确拷贝的。

memcpy在Linux中的实现:

void *memcpy(void *dest, const void *src, size_t count)
{
	char *tmp = dest;
	const char *s = src;
	while (count--)
		*tmp = *s ;
	return dest;
}

memmove在使用过程中要注意一下几点:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

具体的实现:

void* memmove(void* dest, const void* src, size_t n)
{
	char*     d  = (char*) dest;
    const char*  s = (const char*) src;
	if (s>d) // start at beginning of s
    {
         while (n--)
			*d++ = *s++;
    }
    else if (s<d)// start at end of s
    {
		d = d+n-1;
        s = s+n-1;
		while (n--)
			*d-- = *s--;
	}
	return dest;
}

strcpy的实现:

char *strcpy(char *strDest, const char *strSrc)
{
	assert((strDest!=NULL) && (strSrc !=NULL));
    char *address = strDest;     
    while( (*strDest++ = * strSrc++) != '\0') ; 
    return address ;       
}

 

4.字符串连接

#include<string.h>

char *strcat(char *dest,char *src);

char *strncat(char *dest, const char *src, size_t n);

把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0',src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串,返回dest的指针

strcat的实现:

char* cb_strcat(char* dst, char* src) 
{
	assert(src!=NULL);
	char* retAddr = dst;
	 /* --- get last position --- */
	while (*dst++ != '\0');
	dst--;
	while (*dst++ = *src++);
	return retAddr;
}

5.字符串比较

#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);

返回值:

负值表示s1小于s2,0表示s1等于s2,正值表示s1大于s2

strcmp的实现:

int strcmp(char* str, char* str2) 
{
	assert((str!=NULL) && (str2!=NULL));
	char* pStr = str;
	char* pStr2 = str2;
	while (*pStr && *pStr2 && (*pStr==*pStr2)) 
	{
		  pStr++;
		  pStr2++;
	}
	return (*pStr - *pStr2);	//相等则为0 , 前者大于后者大于0, 反之小于0 
}

strncmp的实现:

int strcmp(char* str, char* str2,size_t size) 
{
	assert((str!=NULL) && (str2!=NULL));
	char* pStr = str;
	char* pStr2 = str2;
	while (size--&&*pStr && *pStr2 && (*pStr==*pStr2)) 
	{
		  pStr++;
		  pStr2++;
	}
	return (*pStr - *pStr2);	//相等则为0 , 前者大于后者大于0, 反之小于0 

6.同样是字符/字符串比较

#include <strings.h>

int strcasecmp(const char *s1, const char *s2);

int strncasecmp(const char *s1, const char *s2, size_t n);

忽略大小写的比较,返回值的规则同上

7.字符的匹配

#include <string.h>

char *strchr(const char *s, int c);

char *strrchr(const char *s, int c);

返回值:

如果找到字符c,返回字符串s中指向字符c的指针,如果找不到就返回NULL

8.子串的匹配

#include <string.h>

char *strstr(const char *haystack, const char *needle);

返回值:

如果找到子串,返回值指向子串的开头,如果找不到就返回NULL

char *strstr (char *buf,char *sub)
{
	if (!*sub)
		return buf;
	while (*buf)
    {
		bp = buf;
		sp = sub;
		do 
		{
			if (!*sp)
				return buf;
		} while (*bp++ == *sp++);
		buf += 1;
    }
	return 0;
}

9.分割字符串

待续~~~~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值