基础知识总结-常用字符串函数实现

strcpy

功  能: 将参数src字符串拷贝至参数dest所指的地址

用  法: char *strcpy(char *dest, const char *src)

返回值: 返回参数dest的字符串起始地址

说  明: 如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况,在编写程序时需特别留意,或者用strncpy()来取代

char *strcpy(char *dest, const char *src)
{
    assert(dest != NULL && src != NULL);
    char *result = dest;
    while ((*dest++ = *src++) != '\0')
        ;
    return result;
}

strncpy

功 能: 将字符串src前n个字符拷贝到字符串dest

用 法: char *strncpy(char *dest, const char *src, size_t n)

返回值: 返回参数dest的字符串起始地址

说 明: 不像strcpy(),strncpy()不会向dest追加结束标记'\0';src和dest所指的内存区域不能重叠,且dest必须有足够的空间放置n个字符。

char *strncpy(char *dest, const char *src, size_t n)
{
    assert(dest != NULL && src != NULL);
    char *result = dest;
    while (n-- && (*dest++ = *src++) != '\0')
        ;
    return result;
}

strcat

功 能: 字符串拼接函数

用 法: char *strcat(char *dest, const char *src)

返回值: 返回dest字符串起始地址

说 明: strcat() 会将参数src字符串复制到参数dest所指的字符串尾部;dest最后的结束字符'\0'会被覆盖掉,并在连接后的字符串的尾部再增加一个'\0';dest与src所指的内存空间不能重叠,且dest要有足够的空间来容纳要复制的字符串;

char *strcat(char *dest, const char *src)
{
    assert(dest != NULL && src != NULL);
    char *result = dest;
    while (*dest != '\0')
        ++dest;
    while ((*dest++ = *src++) != '\0')
        ;
    return result;
}

strncat

功 能: 将n个字符追加到字符串的结尾

用 法: char *strncat(char *dest, const char *src, size_t n)

返回值: 返回dest字符串起始地址

说 明: strncat()将会从字符串src的开头拷贝n个字符到dest字符串尾部,dest要有足够的空间来容纳要拷贝的字符串;如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部;strncat()会将dest字符串最后的'\0'覆盖掉,字符追加完成后,再追加'\0';

char *strncat(char *dest, const char *src, size_t n)
{
    assert(dest != NULL && src != NULL);
    char *result = dest;
    while (*dest != '\0')
        ++dest;
    while (n-- && (*dest++ = *src++) != '\0')
        ;
    *dest = '\0';
    return result;
}

strcmp

功 能: 字符串比较

用 法: int strcmp(const char *s1, const char *s2)

返回值: 根据ASCII码比较,若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值

说 明: 它是区分大小写比较的,如果希望不区分大小写进行字符串比较,可以使用stricmp函数

int strcmp(const char *s1, const char *s2)
{
    assert(s1 != NULL && s2 != NULL);
    while (s1 && s2 && (s1 == s2))
    {
        ++s1;
        ++s2;
    }
    return (*s1 - *s2);
}

strlen

功 能: 计算指定的字符串s的长度,不包括结束字符'\0'

用 法: size_t strlen(const char *s)

返回值: 返回字符串s的字符数

说 明: strlen() 函数计算的是字符串的实际长度,遇到第一个'\0'结束;如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到'\0'停止;sizeof返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen()是函数;

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

strstr

功 能: 检索子串在字符串中首次出现的位置

用 法: char *strstr( char *str, char * substr )

char *strstr(char *str, char *substr)
{
    assert(str != NULL && substr != NULL);
    char *s = str;
    char *t = substr;
    for (; *str != '\0'; str++)
    {
        for (s = str, t = substr; *t != '\0' && *s == *t; ++s, ++t)
            ;
        if (*t == '\0')
            return (char *)str;
    }
    return NULL;
}

strpbrk

功 能: 返回两个字符串中首个相同字符的位置

用 法: char *strpbrk(const char *s1, const char *s2)

返回值: 如果s1、s2含有相同的字符,那么返回指向s1中第一个相同字符的指针,否则返回NULL

说 明: strpbrk()不会对结束符'\0'进行检索

char *strpbrk(const char *s1, const char *s2)
{
    assert(s1 != NULL && s2 != NULL);
    const char *s, *t;
    for (s = s1; *s != '\0'; s++)
        for (t = s2; *t != '\0'; t++)
        {
            if (*s == *t)
                return (char *)s;
        }
    return NULL;
}

strtok

功 能 : 根据分界符将字符串分割成一个个片段

用 法 : char *strtok(char *s, const char *delim)

返回值 : 返回下一个分割后的字符串指针,如果已无从分割则返回NULL

说 明 : 当strtok()在参数s的字符串中发现到参数delim的分割字符时则会将该字符改为'\0'字符;在第一次调用时,strtok()必须赋予参数s字符串,往后的调用则将参数s设置成NULL;

char *strtok_r(char *s, const char *delim, char **save_ptr)
{
    char *token;
    if (s == NULL)
        s = *save_ptr;
    /* Scan leading delimiters.  */
    s += strspn(s, delim);
    if (*s == '\0')
        return NULL;
    /* Find the end of the token.  */
    token = s;
    s = strpbrk(token, delim);
    if (s == NULL)
        /* This token finishes the string.  */
        *save_ptr = strchr(token, '\0');
    else
    {
        /* Terminate the token and make *SAVE_PTR point past it.  */
        *s = '\0';
        *save_ptr = s + 1;
    }
    return token;
}

char *strtok(char *s, const char *delim)
{
    static char *last;
    return strtok_r(s, delim, &last);
}

memcpy

实现memcpy()函数及过程总结

void *my_memcpy_byte(void *dst, const void *src, int n)
{
    if (dst == NULL || src == NULL || n <= 0)
        return NULL;

    char *pdst = (char *)dst;
    char *psrc = (char *)src;

    if (pdst > psrc && pdst < psrc + n)
    {
        pdst = pdst + n - 1;
        psrc = psrc + n - 1;
        while (n--)
            *pdst-- = *psrc--;
    }
    else
    {
        while (n--)
            *pdst++ = *psrc++;
    }
    return dst;
}

memmove

仰视源码,实现memmove

void *memmove(void *dst, const void *src, size_t count)
{
    assert(NULL != src && NULL != dst);
    char *tmpdst = (char *)dst;
    char *tmpsrc = (char *)src;

    if (tmpdst <= tmpsrc || tmpdst >= tmpsrc + count)
    {
        while (count--)
        {
            *tmpdst++ = *tmpsrc++;
        }
    }
    else
    {
        tmpdst = tmpdst + count - 1;
        tmpsrc = tmpsrc + count - 1;
        while (count--)
        {
            *tmpdst-- = *tmpsrc--;
        }
    }

    return dst;
}

string 实现

#include <iostream>
#include <cstring>
using namespace std;

class String
{
  public:
    // 默认构造函数
    String(const char *str = NULL);
    // 复制构造函数
    String(const String &str);
    // 析构函数
    ~String();
    // 字符串连接
    String operator+(const String &str);
    // 字符串赋值
    String &operator=(const String &str);
    // 字符串赋值
    String &operator=(const char *str);
    // 判断是否字符串相等
    bool operator==(const String &str);
    // 获取字符串长度
    int length();
    // 重载输出
    friend ostream &operator<<(ostream &o, const String &str);

  private:
    char *data;
    int size;
};
// 构造函数
String::String(const char *str)
{
    if (str == NULL)
    {
        data = new char[1];
        data[0] = '\0';
        size = 0;
    } //if
    else
    {
        size = strlen(str);
        data = new char[size + 1];
        strcpy(data, str);
    } //else
}
// 复制构造函数
String::String(const String &str)
{
    size = str.size;
    data = new char[size + 1];
    strcpy(data, str.data);
}
// 析构函数
String::~String()
{
    delete[] data;
}
// 字符串连接
String String::operator+(const String &str)
{
    String newStr;
    //释放原有空间
    delete[] newStr.data;
    newStr.size = size + str.size;
    newStr.data = new char[newStr.size + 1];
    strcpy(newStr.data, data);
    strcpy(newStr.data + size, str.data);
    return newStr;
}
// 字符串赋值
String &String::operator=(const String &str)
{
    if (data == str.data)
    {
        return *this;
    } //if
    delete[] data;
    size = str.size;
    data = new char[size + 1];
    strcpy(data, str.data);
    return *this;
}
// 字符串赋值
String &String::operator=(const char *str)
{
    if (data == str)
    {
        return *this;
    } //if
    delete[] data;
    size = strlen(str);
    data = new char[size + 1];
    strcpy(data, str);
    return *this;
}
// 判断是否字符串相等
bool String::operator==(const String &str)
{
    return strcmp(data, str.data) == 0;
}
// 获取字符串长度
int String::length()
{
    return size;
}
// 重载输出
ostream &operator<<(ostream &o, const String &str)
{
    o << str.data;
    return o;
}

int main()
{
    String str1("hello ");
    String str2 = "world";
    String str3 = str1 + str2;
    cout << "str1->" << str1 << " size->" << str1.length() << endl;
    cout << "str2->" << str2 << " size->" << str2.length() << endl;
    cout << "str3->" << str3 << " size->" << str3.length() << endl;

    String str4("helloworld");
    if (str3 == str4)
    {
        cout << str3 << " 和 " << str4 << " 是一样的" << endl;
    } //if
    else
    {
        cout << str3 << " 和 " << str4 << " 是不一样的" << endl;
    }

    return 0;
}

// str1->hello  size->6
// str2->world size->5
// str3->hello world size->11
// hello world 和 helloworld 是不一样的
暂无评论

发送评论 编辑评论


				
上一篇
下一篇