字符串学习笔记

字符串函数学习笔记
1. 字符串忽略大小写比较
   strcasecmp : int strcasecmp(const char *s1, const char *s2)
   strncasecmp: int strncasecmp(const char *s1, const char *s2, size_t len)

    函数原型:
    int strcasecmp(const char *s1, const char *s2)
    {
        int c1, c2;

        do {
            c1 = tolower(*s1++);
            c2 = tolower(*s2++);
        } while (c1 == c2 && c1 != 0);
        return c1 - c2;
    }
    
    note: (1) int tolower(int c);
              如果c是大写字母,但是当前语言环境中存在小写表示,则tolower()函数返回其对应的小写字母.
          (2) strcasecmp()函数对字符串s1,s2逐字节比较,忽略字符的大小写,如果s1分别小于,等于,或者大于s2,则返回一个小于,等于,或者大于0的整数.
                若s1为abc,s2为abcd,返回-100(d的ascii);s1为abcd,s2为abc,返回100;
              若s1为abc,s2为abd,返回-1
          (3) strncasecmp()函数是比较前n个字节,其余与strcasecmp一样.

2. 字符串复制
    strcpy : char *strcpy(char *dest, const char *src)
    函数原型:
    char *strcpy(char *dest, const char *src)
    {
        char *tmp = dest;
        
        while ((*dest++ = *src++) != '\0')
            ;
        return tmp;
    }
    note: (1) 把指针src所存地址里的内容付给目的地址, 然后指针自增偏移, 然后比较当前目的地址内的内容是否为'\0',不是继续循环赋值,否则返回最开始的目的地址.

    strncpy:
    char *strncpy(char *dest, const char *src, size_t count)
    {
        char *tmp = dest;

        while (count) {
            if ((*tmp = *src) != 0)
                src++;
            tmp++;
            count++;
        }
        return dest;
    }
    note: (1) 从源地址复制count个字节的内容到目的地址.

    strlcpy:
    size_t strlcpy(char *dest, const char *src, size_t size)
    {
        size_t ret = strlen(src);

        if (size) {
            size_t len = (ret >= size) ? size - 1 : ret;
            memcpy(dest, src, len);
            dest[len] = '\0';
        }
        return ret;
    }
    note: (1) 从源地址中取size个字节的内容,如果size小于src字节个数,则拷贝size-1个字节的内容到目的地址,最后追加'\0', 否则把src的全部拷贝到目的地址, 并追加'\0'.

    实现:
    char *dest = NULL;
    dest = malloc(10);
    char *src = "i love you";
    size_t size = 7;
    strlcpy(dets, src, size);
    puts(dest);
    free(dest);
    dest = NULL;
    结果:i love

3. 字符串拼接
    strcat : char *strcat(char *dest, const char *src)
    函数原型:
    char *strcat(char *dest, const char *src)
    {
        char *tmp = dest;
        while (*dest)
            dest++;
        while ((*dest++ = *src++) != '\0')
            ;
        return tmp;
    }
    note: (1) 把源地址的内容追加到目的地址中.

    char *strncat(char *dest, const char *src, size_t count)
    {
        char *tmp = dest;

        if (count) {
            while (*dest)
                dest++;
            while ((*dest++ = *src++) != '\0') {
                if (--count == 0) {
                    *dest = '\0';
                    break;
                }
            }
        }
        return tmp;
    }
    note: (1) 把源地址的count个字节追加到目的地址中.

4. 字符串比较
    strcmp:
    int strcmp(const char *cs, const char *ct)
    {
        unsigned char c1, c2;

        while (1) {
            c1 = *cs++;
            c2 = *ct++;
            if (c1 != c2)
                return c1 < c2 ? -1 : 1;
            if (!c1)
                break;
        }
        return 0;
    }
    note: (1) 字符串c1 和 c2 逐字符比较,如果c1的ascii值小于c2的ascii的值则返回-1,大于返回1,否则指针偏移继续比较.当c1和c2相等并且c1为'\0'时,证明两字符串相同返回0;

    int strncmp(const char *cs, const char *ct, size_t count);
    两个字符串比较,并限定比较字节个数.

5. 找第一次在字符串中出现的某个字符
    strchr:
    char *strchr(const char *s, int c)
    {
        for (; *s != (char)c; s++)
            if (*s == '\0')
                return NULL;
        retrun (char *)s;
    }
    note: (1) 返回值是匹配到的字符的地址,若匹配失败返回NULL.

    strnchr:
    char *strnchr(const char *s, size_t count, int c);
    在一个字符串中查找某个字符,并限定查找字节个数.

6. 计算字符串长度
    strlen:
    size_t strlen(const char *s)
    {
        const char *sc;

        for (sc = s; *sc != '\0'; ++sc)
            ;
        return sc - s;
    }
    note: (1) strlen()计算的结果不包含'\0'.
7. 计算字符串s1从初始位置开始连续有几个字符在字符串s2中出现
    strspn:
    size_t strspn(const char *s, const char *accept)
    {
        const char *p;
        const char *a;
        size_t count = 0;

        for (p = s; p != '\0'; ++p) {
            for (a = accept; *a != '\0'; ++a) {
                if (*p == *a)
                    break;
            }
            if (*a == '\0')
                return count;
            ++count;
        }
        retrun count;
    }
    note: (1) 返回值是字符串s1从初始位置开始连续在s2字符串存在的字节个数.
          (2) 若s1:ilyoabd; s2:i love you;
              则返回值为4.

8. 查找字符串第一次出现的位置
    strstr:
    char *strstr(const char *s1, const char *s2)
    {
        size_t l1, l2;

        l2 = strlen(s2);
        if (!l2)
            return (char *)s1;
        while (l1 >= l2) {
            l1--;
            if (!memcmp(s1, s2, l2))
                return (char *)s1;
            s1++;
        }
        return NULL;
    }
    note: (1) 在字符串s1中找到子串s2,返回s2在s1中的位置,未找到返回NULL;

9. 拷贝一段内存空间的内容到另一段内存空间
    memmove:
    void *memmove(void *dest, const void *src, size_t count)
    {
        char *tmp;
        const char *s;

        if (dest <= src) {
            tmp = dest;
            s = src;
            while (count--)
                *tmp++ = *src++;
        } else {
            tmp = dest;
            tmp += count;
            s = src;
            s += count;
            while (count--)
                *--tmp = *--s;
        }
        return dest;
    }
    note: (1) 如果目的地址在源地址前面,则不断的把原地址的内容复制到目的地址.
          (2) 如果目的地址在原地址后面,则找到字符串的最后位置从后往前不断的把源地址的内容复制到目的地址.

10. 复制一段存储空间的内容到另一段内存空间
    memcpy:
    void *memcpy(void *dest, const void *src, size_t count)
    {
        char *tmp = dest;
        const char *s = src;

        while (count--)
            *tmp++ = *s++;
        return dest;
    }
    note: (1) 注意防止内存空间覆盖数据.

11. 向一段内存内存空间填充给定的数值count个字节
    memset:
    void *memset(void *s, int c, size_t count)
    {
        char *xs = s;

        while (count--)
            *xs++ = c;
        return s;
    }

12. 拆分字符串
    strsep:
    char *strsep(char **s, const char *ct)
    {
        char *sbegin = *s;
        char *end;

        if (sbegin == NULL)
            return NULL;

        end = strpbrk(sbegin, ct);
        if (end)
            *end++ = '\0';
        *s = end;
        return sbegin;
    }
    note: (1) 被分割的字符串会被改变,所以不能操作存放在静态存储区的字符串常量.
          (2) 分隔符会被替换成'\0'.
          (3) 传递二级指针.
          (4) 指针sbegin保存指针s的地址,当在字符串中找到与分隔符相同的字符时将其替换成'\0',并将其下一个地址传给指针s,然后返回指针sbegin的地址,这样就得到了被分割的第一段字符串,再次调用该函数时,指针s已指向被分割处的下一个位置.
    char *strpbrk(const char *cs, const char *ct)
    {
        const char *sc1, *sc2;

        for (sc1 = cs; *sc1 != '\0'; ++sc1) {
            for (sc2 = ct; *sc2 != '\0'; ++sc2) {
                if (*sc1 == *sc2)
                    return (char *)sc1;
            }
        }
        return NULL;
    }

转载于:https://www.cnblogs.com/frank-zhao19/p/10546193.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值