凯H 2023-04-25 17:00 采纳率: 81%
浏览 102
已结题

这个字符串的代码问题出在哪里


#include<stdio.h>
#define STRINGMAX 100
typedef struct 
{
    char vec[STRINGMAX];   
    int len;
}str;
int LenStr(str *r)
{
    int i=0;
    while(r->vec[i]!='\0')
        i++;
    return i;
}
str *CreateStr(str *r)
{
    gets(r->vec);
    r->len=LenStr(r);
    return r;
}
void ConcatStr(str *r1,str *r2) 
{
    int i;
    printf("r1=%s,r2=%s\n",r1->vec,r2->vec);
    if(r1->len+r2->len>STRINGMAX)
        printf("两个串太长,溢出!\n");
    else
    {
        for(i=0;i<r2->len;i++)
            r1->vec[r1->len+i]=r2->vec[i];
        r1->vec[r1->len+i]='\0';
        r1->len=r1->len+r2->len;
    }
}
void InsStr(str *r,str *r1,int i)
{
    int k;
    if(i>r->len+2||r->len+r1->len>STRINGMAX)
        printf("不能插入\n!");
    else
    {
    for(k=r->len-1;k>=i-1;k--)
            r->vec[r1->len+k]=r->vec[k];
        for(k=0;k<=r1->len;k++)
            r->vec[i-1+k]=r1->vec[k];
        r->len=r->len+r1->len;
    }
}
void DelStr(str *r,int i,int j)
{
    int k;
    if(i+j-1>r->len)
        printf("!\n");
    else
    {
        for(k=i+j-1;k<=r->len;k++,i++)
            r->vec[i-1]=r->vec[k];
        r->len=r->len-j;
    }
}
void main()
{    
    str a,b,c,d;
    str *r=&a,*r1;    
    char choice,p;
    int i,j,ch=1,k;
    r->vec[0]='\0';
    while(ch!=0)
    {
        printf("\n                     串子系统                  ");
        printf("\n***********************************************");
        printf("\n*          1-------创  建  字  串             *");
        printf("\n*          2-------连  接  字  串             *");
        printf("\n*          3-------插  入  子  串             *");
        printf("\n*          4-------删  除  子  串             *");
        printf("\n*          5-------显  示  字  串             *");
        printf("\n*          0-------返          回             *");
        printf("\n***********************************************");
        printf("\n请选择菜单号(0—8):");
        scanf("%c",&choice);
        getchar();
        if(choice=='1')
        {
            printf("\n请输入一个字符串:");
            CreateStr(r);
        }
        else 
            if(choice=='2')
            {
                printf("\n请输入所要连接的串:");
                r1=CreateStr(&b);
                ConcatStr(r,r1);
                printf("\n连接以后的新串值为:");
                puts(r->vec);
            }
            else 
                if(choice=='3')
                {
                    printf("\n请输入在第几个字符前插入:");
                            scanf("%d",&i);
                            getchar();
                            printf("\n请输入所要插入的字符串:");
                            r1=CreateStr(&b);
                            InsStr(r,r1,i);
                }
                else
                    if(choice=='4')
                    {
                        printf("\n请输入从第几个字符开始:");
                        scanf("%d",&i);
                        getchar();
                        printf("\n请输入删除的连续字符数:");
                        scanf("%d",&j);
                        getchar();
                        DelStr(r,i,j);
                    }
                                else
                                    if(choice=='5')
                                    {
                                        printf("\n该串值为:");
                                        if(r->vec[0]=='\0')
                                            printf("空!\n");
                                        else
                                            puts(r->vec);
                                    }
                                    else
                                    if(choice=='0')
                                    ch=0;
    }
}

img

  • 写回答

3条回答 默认 最新

  • 语言-逆行者 2023-04-25 17:03
    关注

    基于new bing加以修改过后的回答:

    1. 问题出在 InsStr 函数中,因为在循环中 r1->len+k 可能会超过字符串 r 的最大长度,导致字符串溢出。修正的方法是在循环中加入一个判断条件 k < STRINGMAX - 1
    1. 在 DelStr 函数中,有一个问题是在从字符串 r 中删除子串时没有考虑到删除后的字符串应该以 '\0' 结束,这可能导致结果不正确。修改的方法是在删除完子串后,在字符串末尾添加 '\0'。此外,在循环中变量 k 和 i 的计算也存在问题,正确的计算应该是 k=i+j-1,即要删除的连续字符的最后一个字符的下标。
    1. 在菜单选择中,当用户输入菜单号后需要加上一个getchar()读取掉换行符,否则下次读取菜单号时会直接读取到上次剩余的换行符,造成错误的输入。
      修改过后:

    img

    img

     
     
    #include<stdio.h>
    #define STRINGMAX 100
    typedef struct 
    {
        char vec[STRINGMAX];   
        int len;
    }str;
    int LenStr(str *r)
    {
        int i=0;
        while(r->vec[i]!='\0')
            i++;
        return i;
    }
    str *CreateStr(str *r)
    {
        gets(r->vec);
        r->len=LenStr(r);
        return r;
    }
    void ConcatStr(str *r1,str *r2) 
    {
        int i;
        printf("r1=%s,r2=%s\n",r1->vec,r2->vec);
        if(r1->len+r2->len>STRINGMAX)
            printf("两个串太长,溢出!\n");
        else
        {
            for(i=0;i<r2->len;i++)
                r1->vec[r1->len+i]=r2->vec[i];
            r1->vec[r1->len+i]='\0';
            r1->len=r1->len+r2->len;
        }
    }
    void InsStr(str *r, str *r1, int i)
    {
        int k;
        if (i > r->len + 2 || r->len + r1->len > STRINGMAX)
            printf("不能插入!\n");
        else
        {
            for (k = r->len - 1; k >= i - 1; k--)
            {
                if (k + r1->len < STRINGMAX - 1)
                    r->vec[k + r1->len] = r->vec[k];
            }
            for (k = 0; k < r1->len; k++)
            {
                if (i - 1 + k < STRINGMAX - 1)
                    r->vec[i - 1 + k] = r1->vec[k];
            }
            r->len = r->len + r1->len;
        }
    }
    
    void DelStr(str *r, int i, int j)
    {
        int k;
        if (i + j - 1 > r->len)
            printf("不能删除!\n");
        else
        {
            for (k = i + j - 1; k <= r->len; ++k)
                r->vec[k - j] = r->vec[k];
            r->len = r->len - j;
            r->vec[r->len] = '\0'; // 添加结束符
        }
    }
    
    void main()
    {    
        str a,b,c,d;
        str *r=&a,*r1;    
        char choice,p;
        int i,j,ch=1,k;
        r->vec[0]='\0';
        while(ch!=0)
        {
            printf("\n                     串子系统                  ");
            printf("\n***********************************************");
            printf("\n*          1-------创  建  字  串             *");
            printf("\n*          2-------连  接  字  串             *");
            printf("\n*          3-------插  入  子  串             *");
            printf("\n*          4-------删  除  子  串             *");
            printf("\n*          5-------显  示  字  串             *");
            printf("\n*          0-------返          回             *");
            printf("\n***********************************************");
            printf("\n请选择菜单号(0—8):");
            scanf("%c",&choice);
            getchar();
            if(choice=='1')
            {
                printf("\n请输入一个字符串:");
                CreateStr(r);
            }
            else 
                if(choice=='2')
                {
                    printf("\n请输入所要连接的串:");
                    r1=CreateStr(&b);
                    ConcatStr(r,r1);
                    printf("\n连接以后的新串值为:");
                    puts(r->vec);
                }
                else 
                    if(choice=='3')
                    {
                        printf("\n请输入在第几个字符前插入:");
                                scanf("%d",&i);
                                getchar();
                                printf("\n请输入所要插入的字符串:");
                                r1=CreateStr(&b);
                                InsStr(r,r1,i);
                    }
                    else
                        if(choice=='4')
                        {
                            printf("\n请输入从第几个字符开始:");
                            scanf("%d",&i);
                            getchar();
                            printf("\n请输入删除的连续字符数:");
                            scanf("%d",&j);
                            getchar();
                            DelStr(r,i,j);
                        }
                                    else
                                        if(choice=='5')
                                        {
                                            printf("\n该串值为:");
                                            if(r->vec[0]=='\0')
                                                printf("空!\n");
                                            else
                                                puts(r->vec);
                                        }
                                        else
                                        if(choice=='0')
                                        ch=0;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月4日
  • 已采纳回答 4月26日
  • 赞助了问题酬金15元 4月25日
  • 请采纳用户回复 4月25日
  • 展开全部

悬赏问题

  • ¥15 这个main已经在filename.obj中定义是什么错 C语言
  • ¥15 使用elementor设计样式
  • ¥15 谁能提供一个中文版的推销咨询网站连接?
  • ¥15 springboot项目程序启动报错
  • ¥15 grlb复位后关闭硬限位开关,移动中仍然会触发停止。
  • ¥20 微信平台收付通的相关问题
  • ¥15 grbl复位后,移动会触发报警Alarm 1
  • ¥15 grbl为何无法移动到比复位坐标更小的坐标?
  • ¥15 pspice找元件和一个问题
  • ¥60 怎样隐藏win7系统进程?