面试中常见的字符串库函数编程

来源:互联网 发布:剑三dbm数据怎么删除 编辑:程序博客网 时间:2024/05/19 13:27

下面对一些常见的关于字符的库函数进行实现,这些也是通常面试中所问的一些问题,需要注意的是有些看起来很简单,但是一定要考虑一些边界条件,否则很容易出错.

strcpy实现

char* strcpy(char* dst,const char* src){    if(dst== nullptr||src== nullptr)  //注意边界条件        return nullptr;    char* pdst =dst;    const char* psrc = src;    while(*psrc!='\0') {    //这里不能写成psrc!='\0'        *pdst++ = *psrc++;    }    *pdst = '\0';    //注意结尾    return dst;}

strncpy实现

char* strncpy(char* dst,const char* src,size_t count) {    if(dst== nullptr||src== nullptr||count<=0)        return dst;    char* pdst =dst;    const char* psrc = src;    while(count--&&*psrc!='\0') {        *pdst++ = *psrc++;    }    *pdst = '\0';    //注意    return dst;}

上述的两个关于拷贝的函数都有问题–其没有考虑到内存的重叠的问题,因此会有下面一个函数作为代替.

memmove实现

void* memmove(void *dst,const void *src,size_t n) {    //判断合法性    if (dst == NULL || src == NULL)        return NULL;    char* pdst = (char*)dst;      //强制转换成char*    const char* psrc=(const char*)src;    //防止内存重叠的处理    if (pdst<psrc) {        for (size_t i = 0;i<n;i++)            *(pdst++)=*(psrc++);    }    else {                    //从后往前        pdst += n-1;        psrc += n-1;        for (size_t i = 0;i<n;i++)            *(pdst--)=*(psrc--);    }    *pdst='\0';    return dst;}

strlen实现

最常见的库函数了,下面是一种实现的方式

size_t mystrlen(const char* src) {    if(src== nullptr) return 0;    size_t count=0;    while(*src!='\0') {        src++;        count++;    }    return count;}

memset实现

这个函数是非常容易出错的,因为它是以字节为单位进行初始化的,因此如果对与int等别的类型进行初始化的时候要非常小心.

//其函数的形式就是标准的库函数形式void* mymemset(void* src,int ch,size_t n){   //注意函数的形式    if(src== nullptr)        return src;    char* psrc = (char*)src;    while(n--){        *psrc++ = static_cast<char>(ch);    }    return src;}

测试

下面对上述的函数进行测试,看出其不同的地方:

#include <iostream>using namespace std;char* strcpy(char* dst,const char* src){    if(dst== nullptr||src== nullptr)        return nullptr;    char* pdst =dst;    const char* psrc = src;    while(*psrc!='\0') {        *pdst++ = *psrc++;    }    *pdst = '\0';    return dst;}char* strncpy(char* dst,const char* src,size_t count) {    if(dst== nullptr||src== nullptr||count<=0)        return dst;    char* pdst =dst;    const char* psrc = src;    while(count--&&*psrc!='\0') {        *pdst++ = *psrc++;    }    *pdst = '\0';    return dst;}void* memmove(void *dst,const void *src,size_t n) {    //判断合法性    if (dst == NULL || src == NULL)        return NULL;    char* pdst = (char*)dst;    const char* psrc=(const char*)src;    //防止内存重叠的处理    if (pdst<psrc) {        for (size_t i = 0;i<n;i++)            *(pdst++)=*(psrc++);    }    else {        pdst += n-1;        psrc += n-1;        for (size_t i = 0;i<n;i++)            *(pdst--)=*(psrc--);    }    *pdst='\0';    return dst;}size_t mystrlen(const char* src) {    if(src== nullptr) return 0;    size_t count=0;    while(*src!='\0') {        src++;        count++;    }    return count;}void* mymemset(void* src,int ch,size_t n){    if(src== nullptr)        return src;    char* psrc = (char*)src;    while(n--){        *psrc++ = static_cast<char>(ch);    }    return src;}int main() {    //两种情况会不同...有内存的重叠    char c1[]="hello,world";    char c2[]="hello,world";    memmove(c2+6,c2+5,5);    strncpy(c1+6,c1+5,5);    cout<<c1<<endl;    cout<<c2<<endl;    ////////////////////////    char t[]="12345";    cout<<mystrlen(t)<<endl;    //5    cout<<sizeof(t)<<endl;      //6 , have '\0'    char* t1 ="12345";    cout<<sizeof(t1)<<endl;     //8 ,pointer,64 machine    cout<<mystrlen(t1)<<endl;   //5    ///////////////////////注意memeset函数的用法    char buf[10];    mymemset(buf,'1',sizeof(buf));    for(int i=0;i<sizeof(buf);i++)        cout<<buf[i]<<" ";    cout<<endl;    int buf1[10];    mymemset(buf1,1,sizeof(buf1));    cout<<sizeof(buf1)<<endl;    for(int i=0;i<sizeof(buf1)/sizeof(int);i++)        cout<<buf1[i]<<" ";    cout<<endl;    return 0;}

…………to be continue

0 0