现在的位置: 首页 > 综合 > 正文

关于字符串(2)

2014年09月05日 ⁄ 综合 ⁄ 共 7457字 ⁄ 字号 评论关闭
//关于string的一些库函数的实现

//strncpy
char *_strncpy(char *strDes, const char *strSrc, unsigned int count)
{
	assert(strDes != NULL && strSrc != NULL);
	char *address = strDes;
	while (count-- && *strSrc != '\0')
		*strDes++ = *strSrc;
	*strDes = '\0';
	return address;
}

//strchr
//查找字符串s中首次出现字符c的位置
char *_strchr(const char *str, int c)
{
	assert(str != NULL);
	for (; *str != (char)c; ++str)
	{
		if (*str == '\0')
			return NULL;
		return str;
	}
}

//strcmp
int _strcmp(const char *s, const char *t)
{
	assert(s != NULL && t != NULL);
	while (*s && *t && *s == *t)
	{
		++s;
		++t;
	}
	return (*s - *t);
}

//strncmp
/* int strncmp(char *str1, char *str2, int maxlen);
 * 比较字符串str1和str2的前maxlen个字符。如果前maxlen字节完全相等,返回值就=0;
 * 在前maxlen字节比较过程中,如果出现str1[n]与str2[n]不等,则返回(str1[n]-str2[n])。
 */
int _strncmp(const char *s, const char *t, unsigned int count)
{
	assert(s != NULL && t != NULL);
	while (*s && *t && *s == *t && count--)
	{
		++s;
		++t;
	}
	return (*s - *t);
}

//strcat
char *_strcat(char *strDes, const char *strSrc)
{
	assert(strDes != NULL && strSrc != NULL);
	char *address = strDes;
	while (*strDes != '\0')
		++strDes;
	while ((*strDes++ = *strSrc++) != '\0')
		NULL;
	return address;
}

//strncat
/*原型:extern char *strncat(char *dest,char *src,int n);
 *用法:#include <string.h>
 *功能:把src所指字符串的前n个字符添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。
 *说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
 */
char *_strncat(char *strDes, const char *strSrc, unsigned int count)
{
	assert(strDes != NULL && strSrc != NULL);
	char *address = strDes;
	while (*strDes != '\0')
		++strDes;
	while (count-- && *strSrc != '\0')
		*strDes++ = *strSrc++;
	*strDes = '\0';
	return address;
}

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

//strdup
//将字符串复制到新的位置
char *_strdup(char *strSrc)
{
	if (strSrc != NULL)
	{
		char *start = strSrc;
		int len = 0;
		while (*strSrc++ != '\0')
			++len;
		//分配新内存
		char *address = (char *)malloc(len + 1);
		assert(address != NULL);
		while ((*address++ = *start++) != '\0')
		return address - (len + 1);	//指针返回到首地址
	}
	return NULL;
}

//strstr
//从字符串str1中查找是否有符串str2,如果有,从str1中的str2位置起,返回str1的指针,如果没有,返回null。
char *_strstr(const char *strSrc, char *str)
{
	assert(strSrc != NULL && str != NULL);
	const char *s = strSrc;
	const char *t = str;
	for (; *strSrc != '\0'; ++strSrc)
	{
		for (s = strSrc, t = str; *s == *t && *t != '\0'; ++s, ++t)
			NULL;
		if (*t == '\0')
			return (char *)strSrc;
	}
	return NULL;
}

//strpbrk
/*原型:extern char *strpbrk(char *s1, char *s2);
 *依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,
 *则停止检验,并返回该字符位置,空字符NULL不包括在内。
 *==>在源字符串(s1)中找出最先含有搜索字符串(s2)中任一字符的位置并返回,若找不到则返回空指针。
 */
char *_strpbrk(const char *strSrc, const char *str)
{
	assert(strSrc != NULL && str != NULL);
	const char *s;
	while (*strSrc != '\0')
	{
		s = str;
		while (*s != '\0')
		{
			if (*strSrc == *s)
				return (char *)strSrc;
			++s;
		}
		++strSrc;
	}
	return NULL;
}

char *_strprbk(const char *str1, const char *str2)
{
	const s1,s2;
	for (s1 = str1; *s1 != '\0'; ++s1)
	{
		for (s2 = str2; *s2 != '\0'; ++s2)
		{
			if (*s1 == *s2)
				return (char *)s1;
		}
	}
	return NULL;
}

//strcspn
/*原型:size_t strcspn(const char *s1,const char *s2);
 *功能:顺序在字符串s1中搜寻与s2中字符的第一个相同字符,包括结束符NULL,
 *返回这个字符在S1中第一次出现的位置。
 */
/*strpbrk和strcspn这两个函数功能相似,
 *区别在于前者返回的是一个指针,而后而返回的是一个数组下标值,
 *或者可以前者为绝对值,而后者为偏移量
 */
int *_strcspn(const char *strSrc, const char *str)
{
	assert(strSrc != NULL && str != NULL);
	const char *t = strSrc;
	const char *s;
	while (*t != '\0')
	{
		s = str
		while (*s != '\0')
		{
			if (*t == *s)
				return t - strSrc;
			++s;
		}
		++t;
	}
	return 0;
}

//strspn
/*size_t strspn (const char *s,const char * accept);
 *(返回字符串中第一个不在指定字符串中出现的字符下标)
 */
int _strspn(const char *strSrc, const char *str)
{
	assert(strSrc != NULL && str != str);
	const char *t = strSrc;
	const char *s;
	while (*t != '\0')
	{
		s = str;
		while (*s != '\0')
		{
			if (*t == *s)
				break;
			++s;
		}
		if (*s == '\0')
			return t - strSrc;
		++t;
	}
}

int _strspn_(const char *s, const char *accept)
{
	const char *p;
	const char *a;
	int count = 0;
	for (p = s; *p != '\0'; ++p)
	{
		for (a = accept; *a != '\0'; ++a)
		{
			if (*p == *a)
				break;
		}
		if (*a == '\0')
			return count;
		
		++count;
	}
	return count;
}

//strrchr
/*原型:char *strrchr(char *str, char c);
 *功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置),
 *		并返回从字符串中的这个位置起,一直到字符串结束的所有字符。如果未能找到指定字符,那么函数将返回NULL。
 */
char *_strrchr(const char *str, int c)
{
	assert(str != NULL);
	const char *s;
	while (*s != '\0')
		++s;
	for (--s; *s != (char) c; --s)
	{
		if (s ==str)
			return NULL;
		return (char *)s;
	}
}

//strrev
/*原型:extern char *strrev(char *s);
 *功能:把字符串s的所有字符的顺序颠倒过来(不包括空字符NULL)
 */
char *_strrev(char *str)
{
	char *s = str, *t = str, c;
	while (*t != '\0')
		++t;
	for (--t; s < t; ++s, --t)
	{
		c = *t;
		*t = *s;
		*s = c;
	}
	return str;
}

//strnset
/*
 *原型: char *strnset(char *str, char ch, unsigned n);
 *功能: 将一个串中的前n个字符都设为指定字符ch
 */
char *_strnset(char *str, int c, unsigned int count)
{
	assert(str != NULL);
	char *s = str;
	for (; *s != '\0' && s - str < count; ++s)
		*s = (char) c;
	return str;
}

/*函数:strset
 *原型:extern char *strset(char *s, char c);
 *功能:把字符串s中的所有字符都设置成字符c
 */
char *_strset(char *str, int c)
{
	assert(str != NULL);
	char *s = str;
	for (; *s != '\0'; ++s)
		*s = (char) c;
	return str;
}

/*函数:strupr
 *原型:extern char *strupr(char *s);
 *功能:将字符串s转换为大写形式
 *说明:只转换s中出现的小写字母,不改变其它字符。返回指向s的指针
 */
char *_strupr(char *str)
{
	assert(str != NULL);
	char *s = str;
	while (*s != '\0')
	{
		if (*s >= 'a' && *s <= 'z')
			*s -= 0x20;
		s++;
	}
	return str;
}

/*函数:strlwr
 *原型:extern char *strlwr(char *s);
 *功能:将字符串s转换为小写形式
 *说明:只转换s中出现的大写字母,不改变其它字符。返回指向s的指针。
 */
char *_strlwr(char *str)
{
	assert(str != NULL);
	char *s = str;
	while (*s != '\0')
	{
		if (*s >= 'A' && *s <= 'Z')
			*s += 0x20;
		s++;
	}
	return str;
}

/*函数:strtok
 *原型:char *strtok(char s[], const char *delim);
 *功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
 *
 *说明:strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串,
 *		参数delim则为分割字符串中包含的所有字符。
 *		当strtok()在参数s的字符串中发现参数delim中包涵的分割字符时,则会将该字符改为\0 字符。
 *		在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。
 *		每次调用成功则返回指向被分割出片段的指针。
 */
char *_strtok(char *strToken, const char *str)
{
	assert(strToken != NULL);
	static char *last;
	//第二次使用strtok时,可用NULL代替strToken,
	//此时,作if判断,strToken == NULL,
	//(strToken = last) != NULL;
	//判断的同时,赋值:strToken = last;
	if (strToken == NULL && (strToken = last) == NULL)
		return NULL;
	
	char *s = strToken;
	const char *t = str;
	while (*s != '\0')
	{
		t = str;
		while (*t != '\0')
		{
			if (*s == *t)
			{
				last = s + 1;
				if (s - strToken == 0)
				{
					strToken = last;
					break;
				}
				*(strToken + (s - strToken) = '\0';
				return strToken;
			}
			++t;
		}
		++s;
	}
	return NULL;
}

/*函数:memcpy
 *原型:void *memcpy(void *dest, const void *src, size_t n);
 *功能:从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
 */
void *_memcpy(void *dest, const void *src, unsigned int count)
{
	assert(dest != NULL && src != NULL);
	char *address = dest;
	while (count--)
	{
		*(char *)dest = *(char *)src;
		//指针后移,一直复制到大小为count时结束
		dest = (char *)dest + 1;
		src = (char *)src + 1;
	}
	return address;
}

/*函数:memccpy
 *原型:extern void *memccpy(void *dest, void *src, unsigned char c, unsigned int count);
 *功能:由src所指内存区域复制不多于count个字节到dest所指内存区域,如果遇到字符c则停止复制
 *返回值:如果c没有被复制,则返回NULL,否则,返回字符c 后面紧挨一个字符位置的指针
 */
void *_memccpy(void *dest, const void *src, int c, unsigned int count)
{
	assert(dest != NULL && src != NULL);
	while (count--)
	{
		*(char *) dest = *(char *) src;
		if (*(char *) src == (char)c)
			return ((char *)dest + 1);
		dest = (char *)dest + 1;
		src = (char *)src + 1;
	}
	return NULL;
}

/*函数:memchr
 *原型:extern void *memchr(const void *buf, int ch, size_t count);
 *功能:从buf所指内存区域的前count个字节查找字符ch
 *说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回NULL
 */
void *_memchr(const void *buf, int c, unsigned int count)
{
	assert(buf != NULL);
	while (count--)
	{
		if (*(char *)buf == (char)c)
			return (void *)buf;
		buf = (char *)buf + 1;
	}
	return NULL;
}

/*函数:memcmp
 *原型:int memcmp(const void *buf1, const void *buf2, unsigned int count);
 *功能:比较内存区域buf1和buf2的前count个字节
 */
int _memcmp(const void *s, const void *t, unsigned int count)
{
	assert(s != NULL && t != NULL);
	while (count--)
	{
		if (*(char *)s && *(char *)t && *(char *)s == *(char *)t)
	}
	return ((char *)s - (char *)t);
}

/*函数:memset
 *原型:void *memset(void *s, int ch, size_t n);
 *功能:将 s 中前 n 个字节用 ch 替换并返回 s 
 */
void *_memset(void *str, int c, unsigned int count)
{
	assert(str != NULL);
	void *s = str;
	while (count--)
	{
		*(char *)s = (char)c;
		s = (char *)s + 1;
	}
	return str;
}

/*函数:memmove
 *原型:void *memmove( void* dest, const void* src,size_tcount );
 *功能:由src所指内存区域复制count个字节到dest所指内存区域。
 */
/*
	memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。
	但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。
	memmove的处理措施:
	1.当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
	2.当源内存的首地址大于目标内存的首地址时,实行正向拷贝
	3.当源内存的首地址小于目标内存的首地址时,实行反向拷贝
*/
void *_memmove(void *dest, const void *src, unsigned int count)
{
	assert(dest != NUll && src != NULL);
	char *pdest = (char *)dest;
	char *psrc = (char *)src;
	if (pdest > psrc && pdest - psrc < count)
	{
		while (count--)
		{
			*(pdest + count) = *(psrc + count);
		}
	}
	else
	{
		while (count--)
		{
			*pdest++ = *psrc++;
		}
	}
	return dest;
}

抱歉!评论已关闭.