C语言字符串常见操作

1. 字符串的拷贝strcpy的实现

char *myStrcpy(char *dst,char *src)
{
    char *ret = dst;
    if(dst == NULL || src == NULL)
    {
        return NULL;
    }
    while((*dst++ = *src++)!= '\0')
        ;
    *dst = '\0';
    return ret;
}


2.返回字符串长度strlen实现

unsigned int myStrlen(const char *src)
{
    // 安全性检查
    if(src == NULL)
    {
        return 0;
    }
    const char *end = src;
    // 返回的是'\0'之前的长度,不把'\0'算在内
    while (*end++ != '\0')
        ;
    return (unsigned int)(end - src);

}

3.字符串连接strcat实现

注意调用者必须保证dst有足够的空间否则造成内存越界

char *myStrcat(char *dst,const char *src)
{
    if(dst == NULL || src == NULL)
    {
        return NULL;
    }
    char *ret = dst;
    // 将指针指向字符串结尾处
    while(*dst != '\0')
        dst++;
    // 执行和strcpy一样的操作
    while ((*dst++ = *src++) != '\0')
        ;
    return ret;
}

4.字符串比较函数strcmp实现

int myStrcmp(char *strA,char *strB)
{
    int val = 0;

    if(strA == NULL || strB == NULL)
    {
        return val;
    }
    // 将指针指到不相等处
    while ((*strA != '\0') && (*strB != '\0') && (*strA == *strB))
    {
        strA++;
        strB++;
    }
    
    // 注 如果不是返回 -1 0 1则此处直接使用 return *strA - *strB 即可
    
    // 不相等要判断是大于还是小于
    if(*strA != *strB)
    {
        val = *strA > *strB ? 1 : -1;
    }
    else
    {
        val = 0;
    }
    
    return val;
}
5. 将一个字符串逆序

讲一个字符串逆序有多重方式实现,下面的三种方式均是在原字符串上操作。

方式一.使用数组的方式操作

char *reversestr(char *str)
{
    char *temp = str;
    int indexLeft = 0;
    int indexRight = 0;
    if (str == NULL)
    {
        return NULL;
    }
    while(*temp != '\0')
    {
        indexRight++;
        temp++;
    }
    //指向最后一个字符'\0'的前一个
    indexRight = indexRight - 1;
    
    while(indexRight > indexLeft)
    {
        char temp = str[indexLeft];
        str[indexLeft++] = str[indexRight];
        str[indexRight--] = temp;
    }

    return str;
    
}

方式二 .使用指针的方式操作

char *reverseStr(char *str)
{
    char *left = str;
    char *right = str;
    if(str == NULL)
    {
        return NULL;
    }
    while (*right != '\0')
    {
        right++;
    }
    right--;
    while (right > left)
    {
        char temp = *right;
        *right++ = *left;
        *left++ = temp;
    }
    return str;
}

方式三.不使用第三的变量 

char *reversestr1(char *str)
{
    char *left = str;
    char *right = str;
    if (str == NULL)
    {
        return NULL;
    }
    while(*right != '\0')
    {
        right++;
    }
    right--;
    /*使用异或运算的特点 a = a^b^b b = a^b^a */
    while (right > left)
    {
        *left = *left ^ *right;
        *right = *left ^ *right;
        *left = *left ^ *right;
        left++;
        right--;
    }
    return str;
}


6.在字符串中找出第一个只出现一次的字符串,如输入"abaccdeff",输出'b'

char firstNotRepeatingChar(char *str)
{
    /* hash表存储 每个可能出现的字符作为索引值 数组内容即为出现的次数 */
    char ret = '\0';
    // 1.建立hashtable
    const int size = 256;
    // 全部初始化为0
    int hashtable[size] = {0};
    char *hashKey = str;
    // 2.记录出现次数
    while(*hashKey != '\0')
    {
        hashtable[*hashKey]++;
        hashKey++;
    }
    // 3.查找返回
    hashKey = str;
    while(*hashKey != '\0')
    {
        if (hashtable[*hashKey] == 1)
        {
            ret = *hashKey;
            return ret;
        }
        hashKey++;
    }
    return ret;

}

7.  整数装换为字符串atoi的实现
char *intToArray(int number, char *str)
{
    if(str == NULL)
    {
        return NULL;
    }
    char *ret = str;
    char *left = str;
    char temp = '\0';
    // 负数的处理
    if(number < 0)
    {
        number = -number;
        *ret++ = '-';
        left++;
    }
    // 辗转对10求余法 分离各个位的数字
    while (number > 0)
    {
        *ret++ = number%10 + '0'; // 将数字转化为ascall码
        number = number/10;
    }
    *ret = '\0';
    ret--;
    
    /* 逆序 */
    while (ret > left)
    {
        temp = *left;
        *left++ = *ret;
        *ret-- = temp;
    }
    return str;
}
8.字符串转为整数 arrayToInt

int arrayToInt(char *str)
{
    // 需考虑字符串是负数 且是否包含字母
    // 包含字母的处理 -123asd455 则为-123
    //              asd122作为0处理
    
    /* 思路: 逐一遍历字符串 为空 或者 为字符就结束遍历 取出的字符逐一*10*/
    long long val = 0;
    int flag = 0;
    char *src = str;
    bool minus = false;
    /* 安全性 */
    if(str == NULL)
    {
        return 0;
    }
    // 处理正负符号的情况 无论正负都占一个位使指针加一
    if(*src == '-')
    {
        src++;
        minus = true;
    }
    else if (*src == '+')
    {
        src++;
    }
    
    while ((*src != '\0') && ((*src - '0' >= 0) && (*src - '0' <= 9)))
    {
        //逐位乘以10
        flag = minus ? -1:1;
        val = val * 10 + flag*(*src - '0');
        /* 处理溢出问题:int最大值0x7FFFFFFF 最小值80000000 */
        if(((minus) && (val > 0x7FFFFFFF)) ||
           ((!minus) && (val < (signed int)0x80000000)))
        {
            val = 0;
            break;
        }
        src++;
    }
    printf("val= %d",(int)val*flag);
    return (int)val;
}

9.查找字符串中最长子串

void findMaxLengthSubstr1(char *src)
{
    char *start = src;
    char *end = src;
    unsigned int maxLength = 0;
    unsigned int tempLength = 0;
    // 此处子串长度不能超过100
    char maxStr[100] = "0";

    if (src == NULL)
    {
        return ;
    }
    while (*end != '\0')
    {
        while(*end != ' ')
        {
            // 到了字符串结尾处则也算是一个子串的结束必须跳出循环
            if (*end == '\0')
            {
                break;
            }
            tempLength++;
            end++;
        }

        // 判断空格之前单词长度是否大于记录的最大长度
        if(maxLength < tempLength)
        {
            maxLength = tempLength;
            // 只能存储长度小于100的 否则直接退出,
            // 原则可以不支持,但必须保证程序没有异常不会挂机
            if (maxLength < 100)
            {
                strncpy(maxStr,start,maxLength);
            }
            else
            {
                printf("The substr too length");
                return;
            }
        }
        // 无论长度是否大于maxLength只要到了间隔符都要指向空格符的下一个位置重新统计
        end++;
        start = end;
        // 临时长度记录值清空,记录下一个子 串的长度
        tempLength = 0;
    }
    printf("maxstr %s\n",maxStr);
    return ;
}

10.替换空格:请实现一个函数,把字符串中的每个空格替换成“%20”例如输入“we are best ”,则输出we%20are%20 best

此题的实际意义是在网络编程中,如果URL中含有特殊的字符如空格、‘#’等可能导致服务器无法获取正常的参数,我们需要将特殊字符转换成服务器可以识别的字符。准换的规则是“%”加上ASCLL的两位十六制表示,如空格的ASCLL值是32则十六进制为0x20

void replaceBlank(char *src,int length)
{
    int oriLength = 0;
    int countBlank = 0;
    int i = 0;
    if (src == NULL && length <= 0)
    {
        return;
    }
    // 统计总长度和空格数
    while (src[i] != '\0')
    {
        oriLength++;
        if(src[i] == ' ')
        {
            countBlank++;
        }
        i++;
    }

    int newLength = oriLength + 2*countBlank;

    // 新长度是否超限制
    if (newLength > length)
    {
        return;
    }
    // 拷贝
    int indexOri = oriLength;
    int indexNew = newLength;
    while (indexOri >= 0 && indexNew > indexOri)
    {
        if (src[indexOri] == ' ')
        {
            src[indexNew--] = '0';
            src[indexNew--] = '2';
            src[indexNew--] = '%';
        }
        else
        {
            src[indexNew--] = src[indexOri];
        }
        indexOri--;
    }
    printf("newstr= %s\n",src);
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值