#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; }