Implement str functions: strlen, strcpy, strstr and atoi

2020/10/16

自己动手实现的四个库函数, 分别是:

  1. strlen
  2. strcpy
  3. strstr
  4. atoi

代码如下:

#include <iostream>
#include <stdio.h>
#include <cstdio>
#include "dbg.h"
#include <string.h>
#include <string>
#include <assert.h>
#include <limits.h>
using namespace std;

/*
 * 实现strlen,获取字符串长度
 */
size_t  strlen(const char *str)
{
    const char *s;
    for (s = str; *s; s++) {}
    return s - str;
}

/*
 * 实现strcpy, 字符串拷贝函数
 */
char *strcpy(char *to, const char* from)
{
    assert(to != NULL && from != NULL); // 注意边界条件
    char *p = to;
    while ((*p++ = *from++) != '\0');
    return to;
}

/*
 * 实现strstr, 子串查找函数
 */

char *str_str(const char *str, const char *sub)
{
    assert(str);
    assert(sub);

    const char *str_p = str;
    const char *start = str; // start记录匹配成功的位置
    const char *sub_p = sub;

    char *res = new char[100]; 
    while (*start)
    {
        str_p = start;
        sub_p = sub;

        // 停止条件
        // 1. 其中一个已经到达'\0'
        // 2. 两个字符不相等
        while (*str_p && *sub_p && *str_p == *sub_p)
        {
            str_p++;
            sub_p++;
        }

        if (*sub_p == '\0')
        {
            //dbg(sub_p);
            strcpy(res, start);
            //dbg(res);
            return res;
        }

        start++; // str指针后移
    }
    return NULL;
}

/* 
 * 实现atoi(), 将一个字符串转化为整数
 * 边界数据:
 * 1. 带有正负号的
 * 2. 有空格的
 * 3. 不是数字的,如字母
 * 4. 溢出的数据
 */
int my_atoi(const char *str)
{
    int num = 0;
    int sign = 1;
    const int len = strlen(str);
    int i = 0, j = 0;
    while (str[i] == ' ' && i < len) i++; // 1. 去除左边空格
    // 2. 带有正负号
    if (str[i] == '+') i++; // 正号直接过
    if (str[i] == '-')      // 负号需要记录下来
    {
        sign = -1;
        i++;
    }

    // 3. 转换
    for (; i < len; i++)
    {
        // 无效检测
        if (str[i] < '0' || str[i] > '9') 
            break;
        // 溢出检测
        if (num > INT_MAX / 10 || 
            (num == INT_MAX / 10 && (str[i] - '0') > INT_MAX % 10))
            return sign == -1 ? INT_MIN  = INT_MAX;

        num = 10 * num + (str[i] - '0');
    }
    return sign * num;
}

int main(int argc, char *argv[])
{
    // 1. strlen
    char str[20] = "helloworld";
    size_t res = strlen(str);
    cout << "length = " << res << endl;
    cout << "====================" << endl;

    // 2. strcpy
    char to[20];
    strcpy(to, str);
    cout << "to = " << to << endl;
    cout << "====================" << endl;

    // 3. strstr
    char *sub = "or";
    dbg(str_str(str, sub));
    cout << "====================" << endl;

    // 4. atoi
    dbg(my_atoi("124153"));
    dbg(my_atoi("-124153000000000000000000000000000"));
    dbg(my_atoi("hhhh"));
    dbg(my_atoi("     132"));

    return 0;
}

运行结果 str

前两个并不难,第三个稍微要考虑一些东西,最后一个需要注意边界情况。