<string.h>里的字符串操作函数是经常要用到的,因此阅读了源码后自己实现了一些:

拷贝函数

void * Mymemcpy(void * sDst, const void * sSrc, size_t count)
{
assert(NULL != sDst && NULL != sSrc);
char* saveDst = (char *)sDst;
const char* saveSrc = (char *)sSrc; for (; 0 < count; ++saveDst, ++saveSrc, --count)
*saveDst = *saveSrc; return (void*)sDst;
} void * Mymemmove(void* sDst, const void* sSrc, size_t count)
{
assert(NULL != sDst && NULL != sSrc);
char* saveDst = (char *)sDst;
const char* saveSrc = (char *)sSrc; if ((saveDst > saveSrc) && (saveDst < saveSrc + count)) for (saveDst += count, saveSrc += count; 0 < count; --count) // copy backwards
*--saveDst = *--saveSrc;
else for (; 0 < count; ++saveDst, ++saveSrc, --count) // copy forwards
*saveDst = *saveSrc; return (void *)sDst;
} char * Mystrcpy(char* sDst, const char* sSrc)
{
assert(NULL != sDst);
char* saveDst = sDst;
for (; '\0' != (*saveDst++ = *sSrc++);)
;
return (char *)sDst;
} char * Mystrncpy(char* sDst, const char* sSrc, size_t count)
{
assert(NULL != sDst && NULL != sSrc);
char* saveDst = sDst; for (; (0 < count) && ('\0' != *sSrc); --count)
*saveDst = *sSrc; for (; 0 < count; --count)
*saveDst++ = '\0'; return (char *)sDst; } void * Mymemset(void* sDst, int ch, size_t count)
{
unsigned char* saveDst = (unsigned char *)sDst;
unsigned char c = ch; for (; (0 < count) && ('\0' != *saveDst); ++saveDst, --count)
*saveDst = c; return (void *)sDst;
}

查找函数

void * Mymemchr(const void* str, const int ch, size_t n)
{
assert(NULL != str);
const unsigned char c = ch;
const unsigned char * ssave = (unsigned char *)str; for (; ('\0' != *ssave) && (0 < n); --n, ++ssave)
if (c == *ssave)
return (void*)ssave; return NULL;
} char * Mystrchr(const char* str, int ch)
{
assert(NULL != str);
const unsigned char c = ch; for (; '\0' != *str; ++str)
if ('\0' == *str)
return NULL; return (char*)str;
} char * Mystrrchr(const char* str, int ch)
{
assert(NULL != str);
const unsigned char c = ch;
const char * ssave = NULL; for (; '\0' != *str; ++ str)
if (c == *str)
ssave = str; return (char *)ssave;
} char * Mystrstr(const char* str1, const char * str2)
{
assert(NULL != str1 && NULL != str2);
if ('\0' == *str2)
return (char*)str1; for (; NULL != (str1 = Mystrchr(str1, *str2)); ++str1)
{
const char * ssave1 = str1;
const char * ssave2 = str2; for (;;)
{
if ('\0' == *++ssave2)
return (char*)str1;
else
if (*++ssave1 != *ssave2)
break;
} } return NULL;
}

连接函数

char * Mystrcat(char * sDst, const char * sSrc)
{
assert(NULL != sDst && NULL != sSrc);
char * ssave = sDst; for (; '\0' != *ssave; ++ssave)
; for (; '\0' != (*ssave = *sSrc); ++ssave, ++sSrc)
; return (char*)sDst;
} char * Mystrncat(char * sDst, const char * sSrc, size_t count)
{
assert(NULL != sDst && NULL != sSrc);
char* ssave = sDst; for (; '\0' != *ssave; ++ssave)
; for (; ('\0' != *sSrc) && (0 < count); --count)
*ssave++ = *sSrc++; *ssave = '\0'; return (char*)sDst;
}

比较函数

int Mymemcmp(const void* str1, const void * str2, size_t n)
{
assert(NULL != str1 && NULL != str2);
const unsigned char * ssave1 = (unsigned char *)str1;
const unsigned char * ssave2 = (unsigned char *)str2; for (; 0 < n; ++ssave1, ++ssave2, --n)
{
if (*ssave1 != *ssave2)
return ((*ssave1 < *ssave2) ? -1 : 1);
else if ('\0' == *ssave1)
return (0); }
return 0;
} int Mystrcmp(const char* str1, const char * str2)
{
assert(NULL != str1 && NULL != str2);
for (; *str1 == *str2; ++str1, ++str2)
if('\0' == *str1 )
return 0; return ((*str1 < *str2) ? -1 : 1);
} int Mystrncmp(const char* str1, const char * str2, size_t n)
{
assert(NULL != str1 && NULL != str2);
for (; 0 < n; ++str1, ++str2, --n)
if (*str1 != *str2)
return ((*str1 < *str2)? -1 : 1);
else if ('\0' == *str1)
return 0; return 0;
} int memcmp(const void* sSrc1, const void* sSrc2, size_t num)
{
assert (NULL != sSrc1 && NULL != sSrc2); const unsigned char* s1 = (const char*)sSrc1;
const unsigned char* s2 = (const char*)sSrc2; for (;0 < num; ++s1, ++s2, --num)
{
if (*s1 != *s2)
return ((*s1 > *s2) ? 1 : -1);
}
return 0;
}

计算字符串长度

size_t strlen(const char* sSrc)
{
assert (NULL != sSrc); const char* s = sSrc, *sv = s; while (*sv != '\0')
++sv;
return (size_t)(sv - s);
}

《C标准库》——之<string.h>的更多相关文章

  1. 彻底弄清c标准库中string.h里的常用函数用法

    在我们平常写的c/c++程序,一些算法题中,我们常常会用到c标准库中string.h文件中的函数,这些函数主要用于处理内存,字符串相关操作,是很有用的工具函数.而且有些时候,在笔试或面试中也会出现让你 ...

  2. 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数

    我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...

  3. 走进C标准库(3)——"stdio.h"中的getc和ungetc

    接前文. 再来看看getc和ungetc的实现.在看这两个函数的实现之前,我们先来想一想这两个函数分别需要做的工作. int getc(FILE *stream) 说明:函数getc从stream指向 ...

  4. 走进C标准库(2)——"stdio.h"中的fopen函数

    其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...

  5. 走进C标准库(1)——assert.h,ctype.h

    默默觉得原来的阅读笔记的名字太土了,改了个名字,叫做走进C标准库. 自己就是菜鸟一只,第一次具体看C标准库,文章参杂了对<the standard C library>的阅读和对源码的一些 ...

  6. C 非标准库(conio.h)

    所谓的 C 标准库(C standard library),是指在 ISO C 或者 POSIX 标准中定义的: POSIX is a superset(超集) of the standard C l ...

  7. 走进C标准库(4)——"stdio.h"中的putc

    花了点时间把园子弄得好看了点,现在继续. 函数名: putc 功  能: 输出一字符到指定流中 用  法: int putc(int ch, FILE *stream); #define _putc_ ...

  8. 走进C标准库(5)——"stdio.h"中的其他部分函数

    函数介绍来自:http://ganquan.info/standard-c/ 函数名: freopen 功  能: 替换一个流 用  法: FILE *freopen(char *filename, ...

  9. 走进C标准库(6)——"string.h"中函数的实现memchr

    我写的memchr: void *memchr(const void *buf, char ch, unsigned count){ unsigned ; while(*(buf++) != ch & ...

  10. 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset

    我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ...

随机推荐

  1. 关于springMVC3.0基于注解方式的项目搭建

    前言:开发了几个月的AS3项目,感觉JAVA都用不太熟练了.刚好这几个抽的空,就把自己以前用过的Spring框架再搭一边, 并完整的记录下来 开发环境:tomcat + mysql+ java 1.所 ...

  2. js中,全局变量与直接添加在window属性的区别

    在js中定义的全局变量是挂在window下的,而window的属性也一样,那么这两者有什么区别呢? 其实这两者还是有小小的区别的,全局变量是不能通过delete操作符删除的,而直接定义在window上 ...

  3. web学习之servlet

    1)web服务软件作用: 把本地资源共享给外部访问 2)tomcat服务器基本操作 : 启动:  %tomcat%/bin/startup.bat 关闭: %tomcat%/bin/shutdown. ...

  4. hdu 1232, disjoint set, linked list vs. rooted tree, a minor but substantial optimization for path c 分类: hdoj 2015-07-16 17:13 116人阅读 评论(0) 收藏

    three version are provided. disjoint set, linked list version with weighted-union heuristic, rooted ...

  5. Titanium studio安装

    在Win7 Titanium Studio的安装过程. 1.准备工作 Titanium存储空间的要求,Titanium Studio 需要1 GB.Android SDK需要1.5 GB.Blackb ...

  6. DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版原创发布-带官方示例程序版

    关于 DotNetBar for Windows Forms 12.5.0.2_冰河之刃重打包版 --------------------11.8.0.8_冰河之刃重打包版-------------- ...

  7. CSS之过渡简单应用—日落西山

    代码: <!DOCTYPE html><html><head> <title>日落西山</title> <meta charset=& ...

  8. RDF和Jena RDF API简介

    这是官方文章<An Introduction to RDF and the Jena RDF API>的译文.原文是在刺猬的温驯这里看到的.其中的图片没法显示了,还有一段丢失了.于是我在此 ...

  9. ASP.NET 中HTML和Form辅助方法

    Form辅助方法 Form最重要的属性就是action和method,action指明form中的数据被提交到哪里,method指明用什么方法,默认为GET,下面是一个简单的例子: <form ...

  10. sed用法

    简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的 ...