关于字符串库函数的实现

#include<stdio.h>
#include<assert.h>
#include<ctype.h>

//strcpy(p, p1) 复制字符串 
///strncpy(p, p1, n) 复制指定长度字符串
char *My_strcpy1(char *des, const char *src, int len1, int len2)
{
    char *p = des;
    assert((len1 >= len2)&&(*src != NULL));
    while(*src != '\0')
    {
        *des = *src;
        des++;
        src++;
    }//while(*des++ = *src++)
    *des = '\0';
    return p;
}
//拷贝
char *My_strcpy2(char *des, const char *src, int len1, int len2)
{
    assert((len1 >= len2)&&(*src != NULL));
    int i;
    for(i = 0; src[i] != '\0'; i++)
    {
        des[i] = src[i];
    }
    des[i] = '\0';
    return des;
}
//拷贝
char *My_strncpy(char *des, const char *src, int len1, int len2, int n)
{
    assert((len1 >= len2)&&(*src != NULL));
    int i;
    for(i = 0; src[i] != '\0' && i < n; i++)
    {
        des[i] = src[i];
    }
    return des;
}
//拷贝

//strlen(p) 取字符串长度
int My_strlen(const char *src)
{
    int temp = 0;
    while(*src != '\0')
    {
        temp++;
        src++;
    }
    return temp;
}
//长度

//strcmp(p, p1) 比较字符串 
//strncmp(p, p1, n) 比较指定长度字符串
int My_strcmp(const char *str1, const char *str2)
{
    assert((*str1 != NULL)&&(*str2 != NULL));
    int temp;
    while((temp = *str1 - *str2) == 0)
    {
        str1++;
        str2++;
    }
    return temp;
}
//比较
int My_strncmp(const char *str1, const char *str2, int n)
{
    assert((*str1 != NULL)&&(*str2 != NULL));
    int i;
    int temp;
    for(i = 0; str2[i] != '\0' && i < n; i++)
    {
        while((temp = *str1 - *str2) == 0)
        {
            str1++;
            str2++;
        }
    }
    return temp;
}
//比较

//strcat(p, p1) 附加字符串 
//strncat(p, p1, n) 附加指定长度字符串
char *My_strcat(char *des, const char *src)
{
    assert(src != NULL);
    char *p = des;
    while(*des != '\0')
    {
        des++;
    }
    while(*src != '\0')
    {
        *des++ = *src++;
    }
    *des = '\0';
    return p;
}
//字符串连接
char *My_strncat(char *des, const char *src, int n)
{
    assert(src != NULL);
    char *p = des;
    while(*des != '\0')
    {
        des++;
    }
    for(int i = 0; *src != '\0' && i < n; i++)
    {
        *des++ = *src++;
    }
    *des = '\0';
    return p;
}
//字符串连接

void Func(char *str1)
{
    assert(*str1 != NULL);
    int flag = 0;
    int word = 0;
    int count = 0;
    while(*str1 != '\0')
    {
        if(*str1 == ' ')
        {
            flag = 0;
        }
        if(isalpha(*str1))
        {
            count++;
            if(*str1 != ' '&& flag == 0)
            {
                flag = 1;
                word++;
            }
        }
        str1++;
    }
    printf("字符个数  %d\n", count);
    printf("单词量  %d\n", word);
}
//字符个数、单词量

char *My_itoa(int num, char *str)
{
    char *p = str;
    int i = 0;
    int j;
    char temp;
    int flag = 1;
    while(num != 0)
    {
        if(num < 0)
        {
            num = -num;
            flag = -1;
        }
        str[i] = num % 10 + '0';
        num = num / 10;
        i++;
    }
    if(flag < 0)
    {
        str[i++] = '-';
    }
    str[i] = '\0';
    i--;
    for(j = 0; j < i; j++, i--)
    {
        temp = str[j];
        str[j] = str[i];
        str[i] = temp;
    }
    return p;
}
//整数转字符
int My_atoi(const char *str)
{
    assert(*str != NULL);
    int flag = 1;
    //int i;
    int num = 0;
    while(isspace(*str) == ' ')
    {
        str++;
    }
    if(*str == '-')
    {
        flag = -1;
        str++;
    }
    else if(*str == '+')
    {
        str++;
    }
    while(*str != '\0' && isdigit(*str))
    {
        num = num * 10 + *str - '0';
        str++;
    }
    return num*flag;
}
//字符转整数

int main()
{
    char str[30];
    char *str4 = "1a2b3";
    char *str5 = "-123";
    char str1[30] = "ab cd ef fe  ";
    char *str3 = "   ab cd ef";
    char *str2 = "tulun";
    int len1 = sizeof(str1)/sizeof(str1[0]);
    int len2 = sizeof(str2)/sizeof(str2[0]);
    printf("My_strcpy1  %s\n", My_strcpy1(str1, str2, len1, len2));
    printf("My_strcpy2  %s\n", My_strcpy2(str1, str2, len1, len2));
    printf("My_strncpy  %s\n", My_strncpy(str1, str2, len1, len2, 3));
    printf("My_strlen  %d\n", My_strlen(str1));
    printf("My_strcmp %d\n", My_strcmp(str3, str2));
    printf("My_strncmp  %d\n", My_strncmp(str3, str2, 3));
    printf("My_strcat  %s\n", My_strcat(str1, str2));
    printf("My_strncat  %s\n", My_strncat(str1, str2, 2));
    printf("My_itoa  %s\n", My_itoa(-123, str));
    printf("My_atoi  %d\n", My_atoi(str4));
    printf("My_atoi  %d\n", My_atoi(str5));
    Func(str1);
    Func(str3);
    getchar();
    return 0;
}

1、返回值的作用:链式表达式

int len = strlen(strcpy(str1, str2));

2、关于const:固定离其最近的
const在 * 之前表示内容不变;
const在 * 之后表示指针不变;

const char *str1 = char const *str2 = "abc";//常量字符串,不能修改指向内容
char *const str2 = "def";//常量指针
str1 = str2;

3、assert函数:断言,准确快速地找到错误(debug条件下)

#include <assert.h>
void assert( int expression );

assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。

4、
c语言中的isalpha,isdigit,islower,isupper等一系列函数

5、*(str + 1) 与 str[1] 存取效率:
(1)*(str + 1)
str本身地址—>取出str存放数据地址—>访问数据
(2)str[1]
str的地址—>str + 1

6、strtok函数

char *strtok(char s[], const char *delim);

1)功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串,所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。

2)扫描字符串s,找到delim(假设指定” “)—–>将s中找到的” “变成0,
(1)第一次调用:

strtok(str, " "); //先从原串首字符开始扫描(strtok通过自定义分隔符分隔字符串),

(2)第二次及多次调用:

strtok(NULL, " "); //再从判断后指针指向的位置开始判断

3)返回值:
每次调用成功则返回指向被分割出片段的指针;
当查找不到delim中的字符时,返回NULL。

扫描二维码关注公众号,回复: 1522104 查看本文章

7、越界问题:
(1)不检验’\0’是否属于其拷贝或计算的字符串对象
strcpy()函数是针对C风格字符串进行拷贝的,即遇’\0’而停止拷贝;
strlen()函数只拷贝字符串的实际显示的字符长度,而不包括’\0’字符
(2)不考虑内存重叠问题

猜你喜欢

转载自blog.csdn.net/qq_39191122/article/details/79561067