C语言-重构string.c系统库函数(3)

简介: 这是重写C语言string.c的部分函数的第3篇文章,前面2篇文章已经重写了部分函数,这篇文章介绍剩下的几个常用函数重写方法。

一、函数介绍

这是重写C语言string.c的部分函数的第3篇文章,前面2篇文章已经重写了下面几个函数:

strdup  字符串拷贝
strchr  字符查找函数 (从头开始)
strrchr 字符查找函数(从尾开始)
strcat strncat  字符串拼接函数
memset 内存初始化函数 (可用于赋初值)
strcmp  字符串比较
strlen  计算字符串长度
strstr  字符串查找
memcmp  内存比较
strcpy  字符串拷贝
memcpy  内存拷贝

这篇文章继续重新的函数如下:

strspn  字符查找 (详细介绍看重写的源码介绍和示例代码)
strpbrk 字符查找函数(查找第一个匹配的字符)
strtok、strsep  字符串分隔---字符串处理中非常常用
bcopy   内存拷贝 与memcpy() 功能相同
memscan、memchr 在内存区域中查找字符

二、重写函数源码

2.1 strspn字符查找

strspn 从参数s字符串的开头查找计算连续的字符,这些字符都是accept字符串中包含的字符。

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;
    }

    return count;
}

示例:
#include <stdio.h>
#include <string.h>
int main()
{
    int i;
    char str[] = "123";
    char accept[] = "1111123hhhhh123hhhhh123hhhhh123hhhh";
    i = strspn(str, accept);
    printf("查找的结果: %d\n", i);
    return 0;
}

2.2 strpbrk字符查找函数(顺序遍历)

strpbrk函数是在源字符串cs中查找最先含有搜索字符串ct中任一字符的位置并返回,如果找不到就返回空指针NULL。
比如: 查找的源字符串是 abcd
要查找的字符串还是78c,那么查找的结果返回就是c。 因为查找的字符串里c在源字符串里匹配。

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;
}

示例:
#include <stdio.h>
#include <string.h>
int main()
{
    const char str1[] = "1234567890abcdefg";
    const char str2[] = "Mbc";
    const char *find_str =NULL;

    find_str = strpbrk(str1, str2);
    if (find_str)
    {
        printf("第一个匹配的字符是: %c\n", *find_str); //b
    }
    else
    {
        printf("未查找到字符");
    }
    return 0;
}

2.3 strtok 字符串分隔

strtok函数 用于字符串的分隔,可以根据特定的字符串、字符分隔字符串,字符串处理比较常用。

strtok函数第一次调用时会把ct字符串中所有在s中出现的字符替换为NULL。然后通过依次调用strtok(NULL, ct)得到各部分子串,详细使用方法看下面的示例代码。

/**
*strtok-将字符串拆分为标记
*/
char * ___strtok;
char * strtok(char * s,const char * ct)
{
    char *sbegin, *send;

    sbegin  = s ? s : ___strtok;
    if (!sbegin) {
        return NULL;
    }
    sbegin += strspn(sbegin,ct);
    if (*sbegin == '\0') {
        ___strtok = NULL;
        return( NULL );
    }
    send = strpbrk( sbegin, ct);
    if (send && *send != '\0')
        *send++ = '\0';
    ___strtok = send;
    return (sbegin);
}


示例代码:
#include <stdio.h>
#include <string.h>
int main()
{
    char str1[] = "123-456-789-abc";
    const char str2[] = "-";
    char *find_str =NULL;

    find_str = strtok(str1, str2);
    if (find_str)
    {
        printf("分隔的字符串: %s\n", find_str);
        while (1)
        {
            find_str = strtok(NULL, str2);
            if (find_str)
            {
                printf("分隔的字符串: %s\n", find_str);
            }
            else
            {
                break;
            }
        }
    }
    return 0;
}

/*
分隔的字符串: 123
分隔的字符串: 456
分隔的字符串: 789
分隔的字符串: abc
* */

strtok的升级版本是strsep函数。

char * strsep(char **s, const char *ct)
{
    char *sbegin = *s, *end;

    if (sbegin == NULL)
        return NULL;

    end = strpbrk(sbegin, ct);
    if (end)
        *end++ = '\0';
    *s = end;

    return sbegin;
}

2.4 bcopy 内存拷贝函数

bcopy 与memcpy 功能一样,但是不检查NULL结尾。

/**
*bcopy-将内存的一个区域复制到另一个区域
*@src:从何处复制
*@dest:复制到哪里
*@count:该区域的大小。
bcopy() 和 memcpy() 功能相同,用来复制内存块的前 n 个字节
需要注意的是 bcopy 与memcpy()相同,参数相反。
*/
char * bcopy(const char * src, char * dest, int count)
{
    char *tmp = dest;

    while (count--)
        *tmp++ = *src++;

    return dest;
}

2.5 memscan 在内存区域中查找字符

memscan 用于在内存区域中查找字符,addr是查找的内存首地址,c是查找的字符,size查找的区域范围.

如果查找成功就返回该字符在内存里的地址,如果没有查找到就返回查找的内存的首地址。

void * memscan(void * addr, int c, size_t size)
{
    unsigned char * p = (unsigned char *) addr;

    while (size) {
        if (*p == c)
            return (void *) p;
        p++;
        size--;
    }
    return (void *) p;
}

memchr功能:

从s所指内存区域的前n个字节查找字符c,当第一次遇到字符c时停止查找,如果成功,返回指向字符c的指针;否则返回NULL。

void *memchr(const void *s, int c, size_t n)
{
    const unsigned char *p = s;
    while (n-- != 0) {
        if ((unsigned char)c == *p++) {
            return (void *)(p-1);
        }
    }
    return NULL;
}
目录
相关文章
|
20天前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
11天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
27 6
|
16天前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
1月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
36 10
|
25天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
30天前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
60 7
|
30天前
|
存储 编译器 程序员
【c语言】函数
本文介绍了C语言中函数的基本概念,包括库函数和自定义函数的定义、使用及示例。库函数如`printf`和`scanf`,通过包含相应的头文件即可使用。自定义函数需指定返回类型、函数名、形式参数等。文中还探讨了函数的调用、形参与实参的区别、return语句的用法、函数嵌套调用、链式访问以及static关键字对变量和函数的影响,强调了static如何改变变量的生命周期和作用域,以及函数的可见性。
30 4
|
1月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
28天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
23 0
|
28天前
|
C语言
【c语言】qsort函数及泛型冒泡排序的模拟实现
本文介绍了C语言中的`qsort`函数及其背后的回调函数概念。`qsort`函数用于对任意类型的数据进行排序,其核心在于通过函数指针调用用户自定义的比较函数。文章还详细讲解了如何实现一个泛型冒泡排序,包括比较函数、交换函数和排序函数的编写,并展示了完整的代码示例。最后,通过实际运行验证了排序的正确性,展示了泛型编程的优势。
20 0

热门文章

最新文章