<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. C# 进程和线程

    一.进程和线程 进程是对一段静态指令序列的动态执行过程,是系统进行资源分配和调度的基本单位.与进程相关的信息包括进程的用户标志.正在执行的已经编译好的程序.程序和数据在存储器中的位置等.同一个进程有可 ...

  2. 面试复习(C++)之快速排序

    #include <iostream> using namespace std; void Quicksort(int *a,int low,int high) { if(low>h ...

  3. 一个简单的游戏开发框架(五.对象Object)

    前面提到我们把行为Action从对象Object中分离了出来,用各种不同的行为组合出对象的功能.大家都知道,面向对象的一个类,就是数据和操作的集合.操作(行为)被分离出来了,数据怎么办呢?操作依赖的数 ...

  4. uboot mmc烧写命令

    mmc write addr blk# cnt 这个命令的作用是将内存上的数据写入mmc中 参数: addr: 从内存读取的位置 blk: 写入到mmc中block位置,这个位置是mmc的0地址的偏移 ...

  5. oracle_空值判断

    Oracle空值测试 比较项目 is null is not null nvl 说明 NULL true false true   null true false true   'NULL' fals ...

  6. linux下用eclipse + GDBserver + JLINK 在线调试(ARM11)

    (一)环境: 目标版:TINY6410 OS:centOS6.5 IDE:eclipse luna CDT:v8.3 GDB:V7.5 (二)环境监理 1.安装cenntos:参考其他相关文章,这里重 ...

  7. 当你刷新当前Table时,刷新后如何回到你上一次所在位置呢?

    第一: 在你刷新前保存所在位置的行号 procedure XXXClass.LockPositionEx;begin DisableControls; FHistoryRecNo := 0; FHis ...

  8. freeCAD预选项编辑器

    freeCAD的预选项系统在 Edit 目录 -> Preferences. freecad的功能分成不同的模块,每一模块负责一个特定的工作台工作.freecad还使用了一个概念叫晚加载,这意味 ...

  9. 如何解决Selenium中"Cannot find function addEventListener in object [object HTMLDocument]"的错误

    project: blog target: how-to-resolve-cannot-find-function-addEventListener-error-in-selenium.md stat ...

  10. C++ Daily 《6》---- 类静态对象与函数静态对象

    C++ 的一个哲学基础是,你不应该为你使用的东西付出代价. class 拥有一个 static 成员,即使从未被用到,它也会被构造和析构: 而 函数拥有一个 static 成员, 如果这个函数从未被调 ...