C库实现-string库

#include <stdio.h>

//copying
void * m_memcpy ( void * destination, const void * source, size_t num );
void * m_memmove ( void * destination, const void * source, size_t num );
void * m_memccpy ( void * destination, const void * source, int c, size_t num );	//not standard
char * m_strcpy ( char * destination, const char * source );
char * m_strncpy ( char * destination, const char * source, size_t num );

//Concatenation
char * m_strcat ( char * destination, const char * source );
char * m_strncat ( char * destination, char * source, size_t num );

//Comparison
int m_memcmp ( const void * ptr1, const void * ptr2, size_t num );
int m_strcmp ( const char * str1, const char * str2 );
int m_strcoll ( const char * str1, const char * str2 );	//similar to m_strcmp, not implemented
int m_strncmp ( const char * str1, const char * str2, size_t num );
size_t m_strxfrm ( char * destination, const char * source, size_t num );	//not implemented

//Searching
void * m_memchr ( void * ptr, int value, size_t num );
char * m_strchr ( char * str, int character );
size_t m_strcspn ( const char * str1, const char * str2 );
char * m_strpbrk ( char * str1, const char * str2 );
char * m_strrchr ( char * str, int character );
size_t m_strspn ( const char * str1, const char * str2 );
char * m_strstr ( char * str1, const char * str2 );
char * m_strtok ( char * str, const char * delimiters );

//Others
void * m_memset ( void * ptr, int value, size_t num );
size_t m_strlen ( const char * str );
char * strerror ( int errnum );	//not implemented
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "C_Library_Implementation.h"

#define MAX_LEN		1000

int m_IsDelimiter(const char c, const char * delimiters);

int main(void)
{
	char des[MAX_LEN] = {0}, src[MAX_LEN] = "hello world";
	
	//m_memcpy(des, src, MAX_LEN);
	
	//m_memmove(des, src, MAX_LEN);
	//m_memmove(src+6, src, 100);
	//puts(src+6);
	
	//m_memccpy(des, src, 'x', MAX_LEN);
	//m_memccpy(des, src, 'r', MAX_LEN);
	//puts(des);
	
	//m_strcpy(des, src);
	//puts(des);
	
	//m_strncpy(des, src, 10);
	//m_strncpy(des, src, 20);
	//puts(des);
	
	//m_strcat(des, src);
	//m_strcat(des, " hello");
	//puts(des);
	
	//m_strncat(des, "hello ", 3);
	//m_strncat(des, src, 20);
	//puts(des);
	
	//m_strncpy(des, "world", MAX_LEN);
	//m_strncpy(src, "world", MAX_LEN);
	//printf("%d\n", m_memcmp(des, src, MAX_LEN));
	
	
	//m_strncpy(des, "world", MAX_LEN);
	//m_strncpy(src, "world", MAX_LEN);
	//printf("%d\n", m_strcmp(des, src));
	
	
	//m_strncpy(des, "worldyy", MAX_LEN);
	//m_strncpy(src, "world", MAX_LEN);
	//printf("%d\n", m_strncmp(des, src, 0));
	//printf("%d\n", m_strncmp(des, src, 5));
	//printf("%d\n", m_strncmp(des, src, 6));
	
	//char *p = memchr(src, 'x', 10);
	//char *p = strchr(src, '\0');
	//if(p)	puts(p);
	//else 	puts("not found");
	
	
	//m_strncpy(des, "hello world", MAX_LEN);
	//m_strncpy(src, "abcd", MAX_LEN);
	//size_t pos = m_strcspn(des, src);
	//printf("%d\n", pos);
	//char *pos = m_strpbrk(des, src);
	//if(pos)	printf("%c\n", *pos);
	//else puts("not found");
	
	/*
	m_strncpy(des, "hello world", MAX_LEN);
	char *pos = m_strrchr(des, 'x');
	if(pos)	printf("%s\n", pos);
	else puts("not found");
	*/
	
	/*
	m_strncpy(des, "hello world", MAX_LEN);
	m_strncpy(src, "abcd", MAX_LEN);
	//m_strncpy(src, "hole", MAX_LEN);
	printf("%d\n", m_strspn(des, src));
	*/
	
	/*
	m_strncpy(des, "hello world", MAX_LEN);
	m_strncpy(src, "world", MAX_LEN);
	char *pos = m_strstr(des, src);
	if(pos)	printf("%s\n", pos);
	else puts("not found");
	*/
	
	m_strncpy(des, "- This, a sample string.", MAX_LEN);
	m_strncpy(src, " ,.-", MAX_LEN);
	char * pch = strtok (des, src);
	while (pch != NULL)
	{
		printf ("%s\n",pch);
		pch = strtok (NULL, src);
	}

	return 0;
}

/*
 * 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
 * 1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。
 * 2.与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。
 * 3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
 * 4.source和destin都不一定是数组,任意的可读写的空间均可。
 */
void * m_memcpy ( void * destination, const void * source, size_t num )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = (char *)destination;
	const char *src = (const char *)source;
	
	while(num--)
	{
		*des++ = *src++;
	}
	return destination;
}

/*
 * memcpy()、 memmove()和memccpy()
 * 这三个函数的功能均是将某个内存块复制到另一个内存块。
 * memmove()与memcpy()一样都是用来拷贝src所指的内存内容前n个字节到dest所指的地址上。
 * 不同的是,当src和dest所指的内存区域重叠时,memmove()仍然可以正确的处理,不过执行效率上会比使用memcpy()略慢些。
 * 第三个函数的功能也是复制内存,但是如果遇到某个特定值时立即停止复制。
 */
void * m_memmove ( void * destination, const void * source, size_t num )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = (char *)destination;
	const char *src = (const char *)source;
	
	if(des < src)
	{
		while(num--)
		{
			*des++ = *src++;
		}
	}
	else
	{
		des += num;
		src += num;
		while(num--)
		{
			//*des-- = *src--;
			*--des = *--src;
		}
	}
	return destination;
}

/*
 * 功能:由src所指内存区域复制不多于count个字节到dest所指内存区域,如果遇到字符c则停止复制。
 * 返回值:如果c没有被复制,则返回NULL,否则,返回一个指向紧接着dest区域后的字符的指针。
 */
void * m_memccpy ( void * destination, const void * source, int c, size_t num )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = (char *)destination;
	const char *src = (const char *)source;
	
	while(num--)
	{
		if(*src == (char)c)
		{
			return des+1;
		}
		*des++ = *src++;
	}
	return NULL;
}

/*
 * Copies the C string pointed by source into the array pointed by destination, including the terminating null character.
 * To avoid overflows, the size of the array pointed by destination shall be long enough
 *  to contain the same C string as source (including the terminating null character), 
 * and should not overlap in memory with source.
 */
char * m_strcpy ( char * destination, const char * source )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = destination;
	while(*source)
	{
		*des++ = *source++;
	}
	*des = 0;
	return destination;
}

/*
 * The strncpy function copies the initial count characters of strSource to strDest and returns strDest. 
 * If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. 
 * If count is greater than the length of strSource, the destination string is padded with null characters up to length count. 
 * The behavior of strncpy is undefined if the source and destination strings overlap.
 */
char * m_strncpy ( char * destination, const char * source, size_t num )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = destination;
	while(num--)
	{
		*des++ = *source;
		if(*source)
		{
			++source;
		}
	}
	return destination;
}

/*
 * Appends a copy of the source string to the destination string. 
 * The terminating null character in destination is overwritten by the first character of source,
 *  and a new null-character is appended at the end of the new string formed by the concatenation of both in destination.
 */
char * m_strcat ( char * destination, const char * source )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = destination;
	while(*des) ++des;
	while(*source)
	{
		*des++ = *source++;
	}
	*des = 0;
	return destination;
}

/*
 * Appends the first num characters of source to destination, plus a terminating null-character. 
 * If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.
 */
char * m_strncat ( char * destination, char * source, size_t num )
{
	assert(NULL!=destination && NULL!=source);
	
	char *des = destination;
	while(*des) ++des;
	while(num--)
	{
		*des++ = *source;
		if(*source)
		{
			++source;
		}
		else
		{
			break;
		}
	}
	*des = 0;
	return destination;
}

/*
 * Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2,
 *  returning zero if they all match or a value different from zero representing which is greater if they do not.
 */
int m_memcmp ( const void * ptr1, const void * ptr2, size_t num )
{
	assert(NULL!=ptr1 && NULL!=ptr2);
	
	const char *p1 = (const char *)ptr1;
	const char *p2 = (const char *)ptr2;
	
	int res = 0;
	while(num-- && !res)
	{
		res = *p1++ - *p2++;
	}
	return res;
}

/*
 * This function starts comparing the first character of each string. 
 * If they are equal to each other, it continues with the following pairs
 *  until the characters differ or until a terminanting null-character is reached.
 */
int m_strcmp ( const char * str1, const char * str2 )
{
	assert(NULL!=str1 && NULL!=str2);
	while (*str1 && *str2 && *str1 == *str2) 
    { 
        ++ str1; 
        ++ str2; 
    } 
    return (*str1 - *str2); //ingenious, '\0' is also compared
}

/*
 * If they are equal to each other, it continues with the following pairs until the characters differ, 
 * until a terminating null-character is reached, or until num characters match in both strings, whichever happens first.
 */
int m_strncmp ( const char * str1, const char * str2, size_t num )
{
	assert(NULL!=str1 && NULL!=str2);
	
	int res = 0;
	while (num-- && !res)
	{
		res = *str1 - *str2;
		if(!*str1 || !*str2)
		{
			return res;
		}
        ++ str1; 
        ++ str2; 
	}
	return res;
}

/*
 * Searches within the first num bytes of the block of memory pointed by ptr
 *  for the first occurrence of value (interpreted as an unsigned char),
 *  and returns a pointer to it.
 */
void * m_memchr ( void * ptr, int value, size_t num )
{
	assert(NULL != ptr);
	char *pos = (char *)ptr;
	while(num--)
	{
		if(*pos == (char)value)
		{
			return (void *)pos;
		}
		++ pos;
	}
	return NULL;
}

/*
 * Returns a pointer to the first occurrence of character in the C string str.
 * The terminating null-character is considered part of the C string. 
 * Therefore, it can also be located to retrieve a pointer to the end of a string.
 */
char * m_strchr ( char * str, int character )
{
	assert(NULL != str);
	while(*str)
	{
		if(*str == (char)character)
		{
			return str;
		}
		++ str;
	}
	return (*str == (char)character) ? str : NULL;
}

/*
 * Scans str1 for the first occurrence of any of the characters that are part of str2,
 *  returning the number of characters of str1 read before this first occurrence.
 * The search includes the terminating null-characters,
 *  so the function will return the length of str1 if none of the characters of str2 are found in str1.
 */
size_t m_strcspn ( const char * str1, const char * str2 )
{
	assert(NULL!=str1 && NULL!=str2);
	
	const char *pos = str1;
	const char *keys;
	while(*pos)
	{
		keys = str2;
		while(*keys)
		{
			if(*pos == *keys++)
			{
				return pos - str1;
			}
		}
		++ pos;
	}
	return pos - str1;
}

/*
 * Returns a pointer to the first occurrence in str1 of any of the characters that are part of str2,
 *  or a null pointer if there are no matches.
 */
char * m_strpbrk ( char * str1, const char * str2 )
{
	assert(NULL!=str1 && NULL!=str2);
	
	char *pos = str1;
	const char *keys;
	while(*pos)
	{
		keys = str2;
		while(*keys)
		{
			if(*pos == *keys++)
			{
				return pos;
			}
		}
		++ pos;
	}
	return NULL;
}

/*
 * Returns a pointer to the first occurrence in str1 of any of the characters that are part of str2, or a null pointer if there are no matches.
 * The search does not include the terminating null-characters.
 */
char * m_strrchr ( char * str, int character )
{
	assert(NULL != str);
	
	char *pos = str;
	while(*pos) ++pos;
	-- pos;
	while(pos >= str)
	{
		if(*pos == (char)character)
		{
			return pos;
		}
		-- pos;
	}
	return NULL;
}

/*
 * The length of the initial portion of str1 containing only characters that appear in str2.
 * Therefore, if all of the characters in str1 are in str2,
 *  the function returns the length of the entire str1 string,
 *  and if the first character in str1 is not in str2, the function returns zero.
 */
size_t m_strspn ( const char * str1, const char * str2 )
{
	assert(NULL!=str1 && NULL!=str2);
	
	const char *pos = str1;
	const char *keys;
	while(*str1)
	{
		keys = str2;
		while(*keys)
		{
			if(*pos == *keys)
			{
				break;
			}
			++ keys;
		}
		if(*keys == '\0')	break;
		++ pos;
	}
	return pos-str1;
}

/*
 * Returns a pointer to the first occurrence of str2 in str1,
 *  or a null pointer if there str2 is not part of str1.
 */
char * m_strstr ( char * str1, const char * str2 )
{
	assert(NULL!=str1 && NULL!=str2);
	
	size_t len2 = m_strlen(str2);
	
	for(; *str1; ++str1)
	{
		if(!m_strncmp(str1, str2, len2))
		{
			return str1;
		}
	}
	return 0;
}

/*
 * A sequence of calls to this function split str into tokens,
 *  which are sequences of contiguous characters spearated by any of the characters
 *  that are part of delimiters.
 */
char * m_strtok ( char * str, const char * delimiters )
{
	assert(NULL!=str && NULL!=delimiters);
	
	static char *start;
	char *end;
	if(str)
	{
		start = str;
	}
	while(*start)
	{
		if(m_IsDelimiter(*start, delimiters))
		{
			++ start;
		}
		else
		{
			break;
		}
	}
	if(*start)
	{
		end = start + 1;
		while(*end)
		{
			if(m_IsDelimiter(*end, delimiters))
			{
				*end = '\0';
				char *pos = start;
				start = end + 1;
				return pos;
			}
			++ end;
		}
		if('\0' == *end)
		{
			char *pos = start;
			start = end;
			return pos;	
		}
	}
	return 0;
}

int m_IsDelimiter(const char c, const char * delimiters)
{
	assert(NULL != delimiters);
	
	while(*delimiters)
	{
		if(c == *delimiters++)
		{
			return 1;
		}
	}
	return 0;
}

/*
 * Sets the first num bytes of the block of memory pointed
 *  by ptr to the specified value (interpreted as an unsigned char).
 */
void * m_memset ( void * ptr, int value, size_t num )
{
	assert(NULL != ptr);
	
	char *p = (char *)ptr;
	while(num--)
	{
		*p++ = (char)value;
	}
	return ptr;
}

/*
 * The length of a C string is determined by the terminating null-character: 
 * A C string is as long as the amount of characters between the beginning of the string
 *  and the terminating null character.
 */
size_t m_strlen ( const char * str )
{
	assert(NULL != str);
	const char *pos = str;
	while(*pos) ++pos;
	return pos - str;
}


你可能感兴趣的:(c,String,function,null,character,returning)