str系列库函数--模拟实现

strlen
  #include <string.h>
  size_t strlen( char *str );

功能:函数返回字符串str 的长度( 即空值结束符之前字符数目)。

非递归实现

size_t my_strlen(const char* src)
{
	assert(src);

	size_t len = 0;
	while (*src++ != ‘\0‘)
		++len;

	return len;
}

递归实现

int my_strlen2(const char* strDest)  //递归求字符串长度
{
	assert(strDest);

	if (‘\0‘ == *strDest)
		return 0;
	else
		return (1 + my_strlen(++strDest));
}
strcpy
  #include <string.h>
  char *strcpy( char *to, const char *from );

功能:复制字符串from 中的字符到字符串to,包括空值结束符。返回值为指针to。

不考虑内存重叠

char* my_strcpy(char* dst, const char* src)
{
	assert(dst && src);

	char* pdst = dst;
	while ((*pdst++ = *src++) != ‘\0‘);

	return dst;
}

考虑内存重叠

char *my_strcpy(char *dst,const char *src)
{
	assert(dst && src);

	char *ret = dst;
	my_memcpy(dst,src,strlen(src)+1);

	return ret;
}

其中my_memcpy实现如下:

void * my_memcpy(void *dst, const void *src, size_t count)
{
	assert(dst && src);

	char* pdst = (char*)dst;
	char* psrc = (char*)src;
	int n = count;

	if (pdst > psrc && pdst < (psrc + count))  //重叠
	{
		for (size_t i = n - 1; i != -1; --i)
			pdst[i] = psrc[i];
	}
	else
	{
		for (size_t i = 0; i < n; ++i)
			pdst[i] = psrc[i];
	}

	return dst;
}
 strncpy
  #include <string.h>
  char *strncpy( char *to, const char *from, size_t count );

功能:将字符串from 中至多count个字符复制到字符串to中。如果字符串from 的长度小于count,其余部分用‘\0‘填补。返回处理完成的字符串。

char* my_strncpy(char* dst, const char* src, size_t n) 
{
	assert(dst && str);

	char* pdst = dst;
	const char* psrc = src;
	while (n && (*pdst++ = *psrc ++) != ‘\0‘)
	{
		--n;
	}
	if (n)  //如果n==0 则下面会死循环
	{
		while (n--)
		{
			*pdst++ = ‘\0‘;
		}
	}

	return dst;
}
 strstr
  #include <string.h>
  char *strstr( const char *str1, const char *str2 );

功能:函数返回一个指针,它指向字符串str2 首次出现于字符串str1中的位置,如果没有找到,返回NULL。

char* my_strstr(const char* src, const char* sub) 
{
	assert(src && sub);

	int sublen = strlen(sub);
	char* srctmp = NULL;
	char* subtmp = NULL;
	while (strlen(src) >= sublen)  //strlen(src)在不断更新,可以提前结束循环
	{
		srctmp = (char*)src;
		subtmp = (char*)sub;

		while (*srctmp == *subtmp)
		{
			if (*subtmp == ‘\0‘)
				return (char*)src;

			++srctmp;
			++subtmp;
		}

		if (*subtmp == ‘\0‘)
			return (char*)src;

		++src;
	}

	return NULL;
}
 strcat
  #include <string.h>
  char *strcat( char *str1, const char *str2 );

功能:函数将字符串str2 连接到str1的末端,并返回指针str1.

char* my_strcat(char* dst, const char* str)
{
	assert(dst && str);

	char* pdst = dst;
	while (*pdst != ‘\0‘)  //注意这里不能为 *pdst++ != ‘\0‘  这样会多加一次!
		++pdst;
	while (*str != ‘\0‘)
		*pdst++ = *str++;

	*pdst = ‘\0‘;

	return dst;
}
 strncat
  #include <string.h>
  char *strncat( char *str1, const char *str2, size_t count );

功能:将字符串from 中至多count个字符连接到字符串to中,追加空值结束符。返回处理完成的字符串。

char* my_strncat(char *dst, const char *str, size_t n)
{
	assert(dst && str);

	char* pdst = dst;
	while (*pdst != ‘\0‘)
		++pdst;
	while (n && (*pdst = *str) != ‘\0‘)
	{
		--n;
		++pdst;  //最好这样做,不要放在while里面
		++str;
	}
	*pdst = ‘\0‘;

	return dst;
}
 strcmp
  #include <string.h>
  int strcmp( const char *str1, const char *str2 );

功能:比较字符串str1 and str2, 返回值如下:


返回值


解释


less than 0


str1 is less than str2


equal to 0


str1 is equal to str2


greater than 0


str1 is greater than str2

int my_strcmp(const char *str1, const char *str2)
{
	assert(str1 && str2);
	const char* pstr1 = str1;
	const char* pstr2 = str2;
	while (*pstr1 && *pstr2 && (*pstr1 == *pstr2))
	{
		++pstr1;
		++pstr2;
	}

	return *pstr1 - *pstr2;
}
 strncmp
  #include <string.h>
  int strncmp( const char *str1, const char *str2, size_t count );

功能:比较字符串str1 和 str2中至多count个字符。返回值如下:


返回值


解释


less than 0


str1 is less than str2


equal to 0


str1 is equal to str2


greater than 0


str1 is greater than str2

如果参数中任一字符串长度小于count, 那么当比较到第一个空值结束符时,就结束处理。

int my_strncmp(const char *str1, const char *str2, size_t n)
{
	assert(str1 && str2 && n > 0);
	const char* pstr1 = str1;
	const char* pstr2 = str2;
	while (--n && *pstr1 && *pstr2 && (*pstr1 == *pstr2))
	{
		++pstr1;
		++pstr2;
	}

	return *pstr1 - *pstr2;
}

时间: 2024-08-07 21:19:17

str系列库函数--模拟实现的相关文章

stm32F4系列库函数版本各模块配置过程

GPIO配置步骤: GPIO_InitTypeDef  GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟 //GPIOF9,F10初始化设置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1对应IO口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//

str系列函数

1.strcat char *strcat(char *dest, const char *src) 连接两个字符串,把src连接到dest后面:返回dest地址. 2.strcmp int strcmp(const char *str1, const char *str2) 比较两个字符串. 当str1指向的字符串大于str2指向的字符串时,返回正数. 当str1指向的字符串等于str2指向的字符串时,返回0. 当str1指向的字符串小于str2指向的字符串时,返回负数 3.strcpy ch

bitmap与2-bitmap使用总结

bitmap是一种简单的数据结构,但在存储空间压缩方面却使用广泛. bitmap就是用一个bit位来标记某个元素是否存在:1表示存在,0表示不存在:而2-bitmap就是用两个bit为来标记某个元素出现的次数:00出现0次,01出现1次,10出现2次及其以上,11无意义. 2-bitmap在内存中的表示如下: [0]                  [1]                [2]              -- |00 00 00 00|00 00 00 00|00 00 00

我要好offer之 str/mem系列手写代码

1. str*系列手写代码 a. 一定要注意末尾'\0'的处理,切记切记 b. 一定要对输入做有效性判断,多用断言就是了 int Strlen(const char* str) { assert(str != NULL); const char* tmp = str; while (*tmp != '\0') { ++tmp; } return tmp - str; } char* Strcpy(char* dst, const char* src) { assert(dst != NULL &

模拟键盘按键,将字符转换为虚拟键码

通过oemKeyScan和MapVirtualKey函数 oemKeyScan可以获得扫描码以及转换状态,状态有shift被按下,ctrl被按下,alt被按下等等. MapVirtualKey将一虚拟键码翻译(映射)成一扫描码或一字符值,或者将一扫描码翻译成一虚拟键码. 1 DWORD sc, shift; 2 unsigned char vkey; 3 char a; 4 CString str = "abc"; 5 for (int i = 0; i<str.GetLengt

C/C++ 笔试题

/////转自http://blog.csdn.net/suxinpingtao51/article/details/8015147#userconsent# 微软亚洲技术中心的面试题!!! 1.进程和线程的差别. 线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程的区别:(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行(3)拥有资源:进程是拥有资源的独立单位,线程不拥有系统资源,但可以访问

C语言面试及答案分析

第一部分:基本概念及其它问答题 1.关键字static的作用是什么? 这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用: 1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变. 2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问.它是一个本地的全局变量. 3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用.那就是,这个函数被限制在声明它的模块的本地范围内使用. 大多

C语言经典面试题目(转的,不过写的的确好!)

第一部分:基本概念及其它问答题 1.关键字static的作用是什么? 这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用: 1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变. 2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问.它是一个本地的全局变量. 3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用.那就是,这个函数被限制在声明它的模块的本地范围内使用. 大多

C语言终极面试及答案分析

http://www.cnblogs.com/Purple_Xiapei/archive/2012/05/10/2495003.html 第一部分:基本概念及其它问答题1.关键字static的作用是什么?这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用:1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变.2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问.它是一个本地的全局变量.3)