• 编程实现C库函数


    1.memcpy函数

    memcpy 函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个size变量控制拷贝的字节数;

    函数原型:void *memcpy(void *dest, void *src, unsigned int count);

    用法:可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可以是int*,short*,char*等等,但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void*强制转化为char*,这样在指针加的时候才会保证每次加一个字节;

     1 /********memcpy()函数原型为:void* memcpy(void* dest, const void* src, size_t n); 返回指向dest的空类型指针*********/
     2 //返回void* 类型的原因,是为了使用链式表达,即strlen((char*)(memcpy(dest,src,n)),这样可以直接计算dest的长度,是程序代码更简洁
     3 /****注意void* 指针的使用,即该函数允许传入任何类型的指针数据****/
     4 void* memcpy(void *dest,const void *src, size_t n)
     5 {
     6     assert((dest != NULL) && (src != NULL));
     7     char *dest_t = (char*)dest;                  //转换成字符型一个个复制拷贝,由于函数拷贝的过程是一个字节一个字节的拷贝的,
     8                                                  //所以实际操作的时候要把void*强制转化为char*,
     9     char *src_f = (char*)src;                    //这样在指针加的时候才会保证每次加一个字节
    10     while (n-- > 0)
    11     {
    12         *(dest_t++) = *(src_f++);
    13     }
    14     return dest;//void* 一定要返回一个值(指针),这个和void不太一样!函数返回指向dest的指针
    15 
    16 }

    注1:与strcpy相比,memcpy并不是遇到''就结束,而是一定会拷贝完n个字节。

        2:如果目标数组dest本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。

    复制代码
    //memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;
    
      char a[100], b[50];
    
      memcpy(b, a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。
    
      strcpy就只能拷贝字符串了,它遇到''就结束拷贝;例:
    
      char a[100], b[50];
    
          strcpy(a,b);
    复制代码

    2.strcpy函数

    写法一、

    1 char * strcpy( char *strDest, const char *strSrc ) 
    2 {
    3  assert( (strDest != NULL) && (strSrc != NULL) );//检测输入指针是否能访问
    4  char *address = strDest; 
    5  while( (*strDest++ = * strSrc++) != ‘’ ); //复制字符串
    6  return address;//返回指针
    7 }

     写法二、

    复制代码
    /********strcpy()函数原型为:char *strcpy(char* dest, const char *src); 返回指向dest的指针*********/
    //返回char* 类型的原因,是为了使用链式表达,即strlen(strcpy(dest,src)),这样可以直接计算dest的长度,是程序代码更简洁
    
    char* strcpy(char *dest, char *src)
    {
        if(dest == NULL || src == NULL)
            return NULL;
        char *res = dest;//保存原始dst的首地址
        while(*src != '')
        {
            *dest = *src;
            dest++;
            src++;
        }
        *dest = '';
        return res;
    }复制代码
    

     3.strcat函数

    功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'')。

    说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

    复制代码
    #include <stdio.h>
    #include <iostream>
    
    using namespace std;
    
    char* strcat(char *dest, char *src)
    {
        if (dest == NULL)
            return NULL;
        if (src == NULL)
            return dest;
        char *head = dest;
        while (*dest != '')
            dest++;
        while (*src != '')
        {
            *dest = *src;
            dest++;
            src++;
        }
        *dest = '';
        return head;
    }
    
    
    int main()
    {
        char dest[] = "nihao";
        char src[] = "zhouyang";
        char *res = strcat(dest, src);
        cout << dest << endl;
        system("pause");
        return 0;
    }
    复制代码

    4.strcmp函数

    功能:比较两个字符串大小。

    实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着比较第二个字符然后第三个字符等等。无论两个字符串是什么样,strcmp函数最多比较到其中一个字符串遇到结束符'/0'为止,就能得出结果。

    返回结果:①str1小于str2,返回负值或者-1(VC返回-1);②str1等于str2,返回0;③str1大于str2,返回正值或者1(VC返回1);

    复制代码
    #include <stdio.h>
    #include <iostream>
    #include <assert.h>
    
    using namespace std;
    
    /****strcmp原型: int strcmp(const char *str1, const char *str2)*****/
    int strcmp(const char *str1, const char *str2)
    {
        assert((str1 != NULL) && (str2 != NULL));
        while ((*str1 != '') && (*str2 != ''))
        {
            if (*str1 == *str2)
            {
                str1++;
                str2++;
            }
            else
            {
                if (*str1 > *str2)
                    return 1;
                else
                    return -1;
            }
        }
        if (*str1 == '' && *str2 == '')
            return 0;
        else if (*str1 == '' && *str2 != '')
            return -1;
        else if (*str1 != '' && *str2 == '')
            return 1;
    }
    
    int main()
    {
        char *str1 = "78";
        char *str2 = "789";
        int res = strcmp(str1, str2);
        cout << res << endl;
        system("pause");
        return 0;
    }
    复制代码

    5.strlen函数

    功能:返回字符串的长度。

    复制代码
    #include <stdio.h>
    #include <iostream>
    #include <assert.h>
    
    
    using namespace std;
    
    /********strlen()函数原型为:int strlen(const char *src); 返回字符串的长度*********/
    size_t strlen(const char *str)
    {
        assert(str != NULL);
        int num = 0;
        while(*str != '')
        {
            str++;
            num++;
        }
        return num;
    }
    
    int main()
    {
        char *str = "123456";
        int temp = strlen(str);
        cout << temp << endl;
        return 0;
    }
    复制代码

    6.strncpy

    功能:将字符串src中最多n个字符复制到字符数组dest中(它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制),返回指向dest的指针。

    要求:如果n > dest串长度,dest栈空间溢出产生崩溃异常。该函数注意的地方和strcpy类似,但是n值需特别注意。

    复制代码
    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    
    /***string.h,char *strncpy(char *dest, const char *src, size_t n),
    把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。**/
    char* mystrncpy(char *dest, const char *src, size_t n)
    {
        if (dest == NULL || src == NULL || n < 0)
            return NULL;
        char *res = dest;
        while (n--)
        {
            *dest = *src;
            dest++;
            src++;
        }
        *dest = '';
        return res;
    }
    
    int main()
    {
        char *src = "hello world";
        char c[10];
        char *res = mystrncpy(c, src, 7);
        cout << res << endl;
        system("pause");
        return 0;
    
    }
    复制代码

     7.strstr函数

    功能:给出字符串str1, str2,判断str2是否为str1的子字符串,如果是,返回str2在str1中对应的起始地址。

    复制代码
    #include <stdio.h>
    #include <iostream>
    #include <assert.h>
    
    using namespace std;
    
    /****
    函数原型:
    extern char *strstr(const char *str1, const char *str2);
    
    str1: 被查找目标 string expression to search.
    str2: 要查找对象 The string expression to find.
    返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
    ****/
    
    const char* strstr(const char *str1, const char *str2)
    {
        if (str1== NULL || str2 == NULL)
            return NULL;
        const char *temp = str1;
        const char *res = str2;while (*str1 != '')
        {
            temp = str1;
            res = str2;
            while (*temp== *res){
                temp++;
                res++;
            }
            if (*res == '')return str1;
            str1++;
    
        }
        return NULL;
    
    }
    int main()
    {
        char *src = "1234567";
        char *dest = "345";
        const char *res = strstr(src, dest);
        cout << res<< endl;//cout<<重载了,会直接输出字符串内容而不是地址
        system("pause");
        return 0;
    }
    复制代码

    8.printf()

    写法一

     1 #include <stdio.h>
     2 #include <stdarg.h>
     3 /*
     4  * 函数名: myPrintf
     5  * 函数功能: 打印格式字符串
     6  * 参数: 1. 包含格式符的字符串地址 2.可变参
     7  * 返回值: 无
     8 */
     9 void myPrintf(char *s, ...)
    10 {
    11     int i = 0;
    12 
    13     /* 可变参第一步 */
    14     va_list va_ptr;
    15 
    16     /* 可变参第二部 */
    17     va_start(va_ptr, s);
    18 
    19     /* 循环打印所有格式字符串 */
    20     while (s[i] != '')
    21     {
    22         /* 普通字符正常打印 */
    23         if (s[i] != '%')
    24         {
    25             putchar(s[i++]);
    26             continue;
    27         }
    28         
    29         /* 格式字符特殊处理 */
    30         switch (s[++i])   // i先++是为了取'%'后面的格式字符
    31         {
    32             /* 根据格式字符的不同来调用不同的函数 */
    33             case 'd': printDeci(va_arg(va_ptr,int));           
    34                         break; 
    35             case 'o': printOct(va_arg(va_ptr,unsigned int));  
    36                         break;
    37             case 'x': printHex(va_arg(va_ptr,unsigned int));  
    38                         break;
    39             case 'c': putchar(va_arg(va_ptr,int));            
    40                         break;
    41             case 'p': printAddr(va_arg(va_ptr,unsigned long));
    42                         break;
    43             case 'f': printFloat(va_arg(va_ptr,double));      
    44                         break;
    45             case 's': printStr(va_arg(va_ptr,char *));
    46                       break;
    47             default : break;
    48         }
    49 
    50         i++; // 下一个字符
    51     }
    52 
    53     /* 可变参最后一步 */
    54     va_end(va_ptr);
    55 }

    写法二、

     1 /*(转载)
     2  * A simple printf function. Only support the following format:
     3  * Code Format
     4  * %c character
     5  * %d signed integers
     6  * %i signed integers
     7  * %s a string of characters
     8  * %o octal
     9  * %x unsigned hexadecimal
    10  */
    11 int my_printf( const char* format, ...)
    12 {
    13     va_list arg;
    14     int done = 0;
    15 
    16     va_start (arg, format); 
    17 
    18     while( *format != '')
    19     {
    20         if( *format == '%')
    21         {
    22             if( *(format+1) == 'c' )
    23             {
    24                 char c = (char)va_arg(arg, int);
    25                 putc(c, stdout);
    26             } else if( *(format+1) == 'd' || *(format+1) == 'i')
    27             {
    28                 char store[20];
    29                 int i = va_arg(arg, int);
    30                 char* str = store;
    31                 itoa(i, store, 10);
    32                 while( *str != '') putc(*str++, stdout); 
    33             } else if( *(format+1) == 'o')
    34             {
    35                 char store[20];
    36                 int i = va_arg(arg, int);
    37                 char* str = store;
    38                 itoa(i, store, 8);
    39                 while( *str != '') putc(*str++, stdout); 
    40             } else if( *(format+1) == 'x')
    41             {
    42                 char store[20];
    43                 int i = va_arg(arg, int);
    44                 char* str = store;
    45                 itoa(i, store, 16);
    46                 while( *str != '') putc(*str++, stdout); 
    47             } else if( *(format+1) == 's' )
    48             {
    49                 char* str = va_arg(arg, char*);
    50                 while( *str != '') putc(*str++, stdout);
    51             }
    52 
    53             // Skip this two characters.
    54 
    55             format += 2;
    56         } else {
    57             putc(*format++, stdout);
    58         }
    59     }
    60 
    61     va_end (arg);
    62 
    63     return done;
    64 }
      1 C常用库函数实现
      2 // ---------- strlen -------------
      3 int strlen(char *t){
      4     int length = 0;
      5     if(t == NULL)
      6         return -1;
      7  
      8     while (*t != '') {
      9         t++;
     10         length++;
     11     }
     12     return length;
     13 }
     14  
     15 size_t strlen(const char *s)
     16 {
     17     const char *sc;
     18  
     19     for (sc = s; *sc != ''; ++sc);
     20  
     21     return sc - s;
     22 }
     23  
     24 // ---------- trim -------------
     25  
     26 void ltrim ( char *s )
     27 {
     28     char *p;
     29     p = s;
     30     while ( *p == ' ' || *p == '	' ) {p++;}
     31     strcpy ( s,p );
     32 }
     33  
     34 void rtrim ( char *s )
     35 {
     36     int i;
     37  
     38     i = strlen ( s )-1;
     39     while ( ( s[i] == ' ' || s[i] == '	' ) && i >= 0 ) {i--;};
     40     s[i+1] = '';
     41 }
     42  
     43 void trim ( char *s )
     44 {
     45     ltrim ( s );
     46     rtrim ( s );
     47 }
     48  
     49 // ---------- strcpy -------------
     50  
     51 char *strcpy(char *dest, const char *src)
     52 {
     53     char *tmp = dest;
     54  
     55     while ((*dest++ = *src++) != '');
     56  
     57     return tmp;
     58 }
     59  
     60 // ---------- strcat -------------
     61  
     62 char *strcat(char *dest, const char *src)
     63 {
     64     char *tmp = dest;
     65  
     66     while (*dest)
     67         dest++;
     68     while ((*dest++ = *src++) != '');
     69  
     70     return tmp;
     71 }
     72  
     73 // ---------- strstr -------------
     74  
     75 char *strstr(const char *s1, const char *s2)
     76 {
     77     int l1, l2;
     78  
     79     l2 = strlen(s2);
     80     if (!l2)
     81         return (char *)s1;
     82     l1 = strlen(s1);
     83     while (l1 >= l2) {
     84         l1--;
     85         if (!memcmp(s1, s2, l2))
     86             return (char *)s1;
     87         s1++;
     88     }
     89  
     90     return NULL;
     91 }
     92  
     93  
     94 // ---------- memcmp -------------
     95  
     96 int memcmp(char *cs, char *ct, size_t count)
     97 {
     98     char *su1, *su2;
     99     int res = 0;
    100  
    101     for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
    102         if ((res = *su1 - *su2) != 0)
    103             break;
    104     return res;
    105 }
    106  
    107 // ---------- strcmp -------------
    108  
    109 int strcmp(const char *cs, const char *ct)
    110 {
    111     unsigned char c1, c2;
    112  
    113     while (1) {
    114         c1 = *cs++;
    115         c2 = *ct++;
    116         if (c1 != c2)
    117             return c1 < c2 ? -1 : 1;
    118         if (!c1)
    119             break;
    120     }
    121  
    122     return 0;
    123 }
  • 相关阅读:
    docker 数据卷 ---- 进阶篇
    docker 数据卷 ---- 基础篇
    python做基本的图像处理
    conv1d UpSampling1D aotoencoder 自编码代码摘录
    python daal test
    python dict 构造函数性能比较
    CNN autoencoder 进行异常检测——TODO,使用keras进行测试
    利用CNN进行流量识别 本质上就是将流量视作一个图像
    Deep Belief Network简介——本质上是在做逐层无监督学习,每次学习一层网络结构再逐步加深网络
    python pipe stdout 实现cat|grep 功能
  • 原文地址:https://www.cnblogs.com/ordinary-world/p/9973760.html
Copyright © 2020-2023  润新知