C语言每日一练——第59天:将字符串中间的*号全部删除

该篇博客介绍了如何使用C语言处理字符串,特别是删除字符串中除了首尾外的所有*号。博主提供了两种解决方案,一种是新建字符数组存储处理后的字符串,另一种则直接在原字符串上进行移位删除。文章通过详细分析和代码实现展示了这两种方法,并给出了运行结果和参考代码。对于全*号的特殊情况也进行了讨论。
摘要由CSDN通过智能技术生成

C语言每日一练
2021年11月15日

题目描述

现在有一串字符需要输入,规定输入的字符串中只包含字母和*号。请编写程序,实现以下功能:除了字符串前后的*号之外,将串中其他的*号全部删除。

例如,假设输入的字符串为****A*BC*DEF*G********,删除串中的*号后,字符串变为****ABDEFG********

分析

我的思路:
一个简单直观的方法:新建一个用来输出的字符数组,将符合条件的字符存入数组再输出即可。

字符串开头的*号,我们可以通过一个指针来遍历,如果指针指向的字符是*号,则将其存入输出数组中,直到检测到非*号的字符,但这种单向遍历的方法不好判断字符串尾部的*号,比如***aaa***bb***,字符串中间是连续的*,和尾部的*号没有很明显的差别,这时单个字符的检测就不方便了。

但是,我们可以在定义一个右指针,从字符串最后的字符向前遍历,直到检测到非*的字符,这时它就指向尾部*号起点的前面,这时左指针和右指针之间的字符即为中间区域
右指针向前移动要考虑是否会出界,可以和原字符串或左指针进行地址比较,避免出现越界问题

最后,将字符串中间区域的非*字符和以右指针开头的字符串存入输出字符数组即可。

代码实现

代码的核心步骤

  1. 右指针向左移动,直到非*位置或字符串开头,如果到了字符串开头,直接输出原字符串。
  2. 左指针向右移动,将*存入输出字符数组,直到非*的位置。
  3. 将中间区域的非*字符存入输出字符数组。
  4. 将右指针指向的字符串存入输出字符数组。
#include <stdio.h>
#include <string.h>

#define MAX_LANGTH 50               //字符数组最大长度

int main()
{
    char str[MAX_LANGTH] = {0};     //目标字符串
    char *str_left = str;           //从左向右判断*号
    char *str_right = NULL;         //指向尾部*的起点
    char str_tmp[MAX_LANGTH] = {0}; //结果字符数组
    int i = 0;

    printf("请输入一个字符串,必须带*号\n");
    gets(str);
    str_right = &str[strlen(str) - 1]; //指向字符串末尾

    /* 尾部指针向左移动,直到没有检测到*号或到达字符串开头 */
    while(*str_right == '*' && str_right != str_left)
        str_right--;               //移到到尾部*的起点之前

    if(str_right == str_left)      //如果字符串只有*号
    {
        printf("删除中间的*号后:%s\n", str);
        return 0;
    }

    /* 头部指针向右移动,直到检测到非*的其他符号 */
    while(*str_left == '*')
        str_tmp[i++] = *str_left++;  //将头部的*存入输出字符数组中

    /* 开始删除字符串中间的*号 */
    while(str_left != str_right)   //判断范围为字符串中间区域
    {
        if(*str_left != '*')
            str_tmp[i++] = *str_left; //将除*号以外的字符存入输出字符数组中
        str_left++;
    }

    /* 将后面的所有字符都追加到输出字符串中 */
    while(*str_right != '\0')
        str_tmp[i++] = *str_right++;
        
    str_tmp[i] = '\0';             //不要忘了'\0'
    printf("删除中间的*号后:%s\n", str_tmp);
    return 0;
}

运行结果

在这里插入图片描述

网上参考

这份代码没有新建字符数组,而是在原字符串上进行移位删除,具体实现思路见原文,链接如下:
原文链接:http://c.biancheng.net/cpp/html/3374.html
但是,这份代码有一个不足之处:没有考虑全是*号的情况(见文末)。

#include <stdio.h>
int fun(char *a, char *h, char *p)
{
    int i, j;
    /*删除指针h与p之间的所有“*”*/
    for(i=0,j=0; &h[i]<p; i++)
        if(h[i]!='*')
            h[j++]=h[i];
    /*将指针p至字符串尾部的所有字符前移*/
    for(i=0; p[i]; i++,j++)
        h[j]=p[i];
    h[j]='\0';  /*在字符串尾部添加结束标志*/
    return 0;
}
int main( )
{
    char s[81], *t, *f;
    printf("Enter a string :\n");
    gets(s);  /*输入字符串*/
    t=f=s;  /*用字符指针t、f指向串s*/
   
    while(*t)
        t++;
    t--;  /*将指针t定位到字符串中最后一个字符*/
    while(*t == '*')  /*指针t指向字符串中最后一个字符*/
        t--;
    while (*f == '*')  /*指针f指向字符串中第一个字符*/
        f++;
    fun(s, f, t);
    printf("The string after deleted:\n");  /*输出结果*/
    puts(s);
    return 0;
}

如果输入一个只包含*号的字符串,程序将会进入死循环
在这里插入图片描述

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小辉_Super

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值