字符串操作

来源:互联网 发布:意德法家 知乎 编辑:程序博客网 时间:2024/05/17 04:19

总结下字符串操作函数,然后自己再实现下,就这样。

1.初始化字符串

#include <string.h>

void *memset(void *s, int c, size_t n);

返回值:和s的指向相同

说明: memset函数把s所指的内存地址开始的n个字节都填充为c的值。通常c的值为0,把一块内存区清零。例如定义char buf[10];,如果它是全局变量或静态变量,则自动初始化为0(位于.bss段),如果它是函数的局部变量,则初值不确定,可以用memset(buf, 0, 10)清零,由malloc分配的内存初值也是不确定的,也可以用memset清零。

具体的实现:

void * memset(void* buffer, int c, int count){char* pvTo=(char*)buffer;assert(buffer != NULL);while(count-->0)*pvTo++=(char)c;return buffer;}


 

2,求字符串的长度

#include <string.h>

size_t strlen(const char *s);

返回值:字符串的长度

说明:strlen函数返回s所指的字符串的长度。该函数从s所指的第一个字符开始找'\0'字符,一旦找到就返回,返回的长度不包括'\0'字符在内。例如定义char buf[]= "hello";,则strlen(buf)的值是5,但要注意,如果定义char buf[5] = "hello";,则调用strlen(buf)是危险的,会造成数组访问越界。

具体实现代码:

size_t strlen(const char* str) {assert(str!=NULL);int len = 0;while (*str!='\0') /**< '\0', stop */{str++;len++ ;}return len;}

 

3.字符串拷贝

#include<string.h>

void *memcpy(void *dest, const void *src, size_t n);

void *memmove(void *dest, const void *src, size_t n);

char *strcpy(char *dest,const char *src);

返回值:dest指向哪,返回的指针就指向哪

memcpy函数从src所指的内存地址拷贝n个字节到dest所指的内存地址,和strncpy不同,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。这里的命名规律是,以str开头的函数处理以'\0'结尾的字符串,而以mem开头的函数则不关心'\0'字符,或者说这些函数并不把参数当字符串看待,因此参数的指针类型是void *而非char *

memmove也是从src所指的内存地址拷贝n个字节到dest所指的内存地址,虽然叫move但其实也是拷贝而非移动。但是和memcpy有一点不同,memcpy的两个参数srcdest所指的内存区间如果重叠则无法保证正确拷贝,而memmove却可以正确拷贝。假设定义了一个数组char buf[20] = "hello world\n";,如果想把其中的字符串往后移动一个字节(变成"hhello world\n"),调用memcpy(buf + 1, buf, 13)是无法保证正确拷贝的。

memcpy在Linux中的实现:

void *memcpy(void *dest, const void *src, size_t count){char *tmp = dest;const char *s = src;while (count--)*tmp = *s ;return dest;}

memmove在使用过程中要注意一下几点:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

具体的实现:

void* memmove(void* dest, const void* src, size_t n){char*     d  = (char*) dest;    const char*  s = (const char*) src;if (s>d) // start at beginning of s    {         while (n--)*d++ = *s++;    }    else if (s<d)// start at end of s    {d = d+n-1;        s = s+n-1;while (n--)*d-- = *s--;}return dest;}

strcpy的实现:

char *strcpy(char *strDest, const char *strSrc){assert((strDest!=NULL) && (strSrc !=NULL));    char *address = strDest;         while( (*strDest++ = * strSrc++) != '\0') ;     return address ;       }

 

4.字符串连接

#include<string.h>

char *strcat(char *dest,char *src);

char *strncat(char *dest, const char *src, size_t n);

把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0',src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串,返回dest的指针

strcat的实现:

char* cb_strcat(char* dst, char* src) {assert(src!=NULL);char* retAddr = dst; /* --- get last position --- */while (*dst++ != '\0');dst--;while (*dst++ = *src++);return retAddr;}

5.字符串比较

#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);

返回值:

负值表示s1小于s2,0表示s1等于s2,正值表示s1大于s2

strcmp的实现:

int strcmp(char* str, char* str2) {assert((str!=NULL) && (str2!=NULL));char* pStr = str;char* pStr2 = str2;while (*pStr && *pStr2 && (*pStr==*pStr2)) {  pStr++;  pStr2++;}return (*pStr - *pStr2);//相等则为0 , 前者大于后者大于0, 反之小于0 }

strncmp的实现:

int strcmp(char* str, char* str2,size_t size) {assert((str!=NULL) && (str2!=NULL));char* pStr = str;char* pStr2 = str2;while (size--&&*pStr && *pStr2 && (*pStr==*pStr2)) {  pStr++;  pStr2++;}return (*pStr - *pStr2);//相等则为0 , 前者大于后者大于0, 反之小于0 

6.同样是字符/字符串比较

#include <strings.h>

int strcasecmp(const char *s1, const char *s2);

int strncasecmp(const char *s1, const char *s2, size_t n);

忽略大小写的比较,返回值的规则同上

7.字符的匹配

#include <string.h>

char *strchr(const char *s, int c);

char *strrchr(const char *s, int c);

返回值:

如果找到字符c,返回字符串s中指向字符c的指针,如果找不到就返回NULL

8.子串的匹配

#include <string.h>

char *strstr(const char *haystack, const char *needle);

返回值:

如果找到子串,返回值指向子串的开头,如果找不到就返回NULL

char *strstr (char *buf,char *sub){if (!*sub)return buf;while (*buf)    {bp = buf;sp = sub;do {if (!*sp)return buf;} while (*bp++ == *sp++);buf += 1;    }return 0;}

9.分割字符串

待续~~~~

 

原创粉丝点击