【零散隨筆】C語言字符串操作函數的模擬實現

/*
* 重新封裝C字符串的部分函數
* 包括strlen,strcpy,strcat,strcmp,strchr(strcpy,strcat,strchr查閱資料之後進行了優化)
* memcpy,memmove
* strncpy,strncat,strncmp
* KMP算法實現strstr暫未完成   2019.4.18
*/

#include<stdio.h>
#include<Windows.h>
#include<assert.h>

size_t mystrlen(const char* str)
{
	size_t count = 0;
	if (str = nullptr)
		return count;
	while (*str != '\0')
		count++; str++;
	return count;
}

char* mystrcpy(char* dest, const char* source)
{
	if (source == nullptr || dest == nullptr)
		return NULL;
	while (*source != '\0'){
		*dest = *source;
		dest++; source++;
	}
	*dest = '\0';
	return dest;
}

char* mystrcpyV2(char* dest, const char* source)
{
	if (source == nullptr || dest == nullptr)
		assert(NULL);
	//保護目標串值??爲什麼?dest不就是臨時變量麼?
	char* tmp = dest;
	//while ((*tmp++ = *source++) != '\0');
	while (*tmp++ = *source++);
	return tmp;
}

char* mystrcat(char* dest, const char* source)
{
	if (source == nullptr || dest == nullptr)
		return NULL;
	while (*dest != '\0')
		dest++;
	mystrcpy(dest, source);
	return dest;
}

char* mystrcatV2(char* dest, const char* source)//faststrcat
{
	if (source == nullptr || dest == nullptr)
		assert(NULL);
	//while (*dest++)這是個坑,不能這樣寫,會使dest多++一次,dest原來的/0沒有被覆蓋
	while (*dest)
		dest++;
	while (*dest++ = *source++);
	//FastStrcat函數每次返回拼接後的字符串尾部,即指向結束符所在位置。
	//下次調用時便不再需要掃描整串,從而提高執行效率。可以優化第一層循環找\0的過程。
	return --dest;
}

char* mystrchr(char* str, int ascll)
{
	if (str == nullptr){
		return NULL;
	}
	while (*str != '\0'){
		if ((int)*str == ascll){
			char *cutstr = str;
			return cutstr;
		}str++;
	}return NULL;
}

char* mystrchrV2(char *s, char c)
{
	assert(s);
	while (*s != '\0' && *s != c)
		++s;
	return *s == c ? s : NULL;
}

int mystrcmp(const char* str1, const char* str2)
{
	if (str1 == nullptr || str2 == nullptr)
		return NULL;
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++; str2++;
	}
	return *str1 > *str2 ? 1 : -1;
}

void * mymemcpy(void * dest, const void * source, size_t num)
{
	void* ret = dest;
	while (num--){
		*(char*)dest = *(char*)source;
		dest = (char*)dest + 1;//(char*)dest++;爲什麼這樣寫會報錯???
		source = (char*)source + 1;
	}
	return ret;
}

void* mymemmove(void * dst, const void * src, size_t count)
{
	void * ret = dst;
	if (dst <= src || (char *)dst >= ((char *)src + count)) {
		//不重疊
		while (count--) {
			*(char *)dst = *(char *)src;
			dst = (char *)dst + 1;
			src = (char *)src + 1;
		}
	}
	else {//重疊
		dst = (char *)dst + count - 1;//此處-1是個細節,不然會多拷一個單位
		src = (char *)src + count - 1;
		while (count--) {
			*(char *)dst = *(char *)src;
			dst = (char *)dst - 1;
			src = (char *)src - 1;
		}
	}
	return(ret);
}

//strstr by kmp
//char * mystrstr(const char *, const char *);

char * mystrncpy(char * destination, const char * source, size_t num)
{
	if (source == nullptr || destination == nullptr)
		assert(NULL);
	char* Dtmp = destination;
	while (*source != '\0'&& num > 0){
		num--;
		*Dtmp++ = *source++;
	}*Dtmp = '\0';
	return destination;
		
}

char * mystrncat(char * destination, const char * source, size_t num)
{
	if (source == nullptr || destination == nullptr)
		assert(NULL);

	char* tmp = destination;
	while (*tmp != '\0'){
		tmp++;
	}
	while (num > 0){
		num--;
		*tmp++ = *source++;
	}*tmp = '\0';
	return destination;
}

int mystrncmp(const char* str1, const char* str2, size_t num)
{
	if (str1 == nullptr || str2 == nullptr)
		return NULL;
	while (num > 0){
		num--;
		if (*str1 != *str2 || *str1 == '\0' || *str2 == '\0')
			return *str1 > *str2 ? 1 : -1;
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章