pta天体赛-L1-094 剪切粘贴

ptaL1-094 剪切粘贴
以下的代码总是出现段错误的问题,请大家麻烦帮忙看一下到底是那里的问题。本人刚学c语言,水平不高,代码写的也不够简洁,还请见谅
题目如下:

使用计算机进行文本编辑时常见的功能是剪切功能(快捷键:Ctrl + X)。请实现一个简单的具有剪切和粘贴功能的文本编辑工具。

工具需要完成一系列剪切后粘贴的操作,每次操作分为两步:

剪切:给定需操作的起始位置和结束位置,将当前字符串中起始位置到结束位置部分的字符串放入剪贴板中,并删除当前字符串对应位置的内容。例如,当前字符串为 abcdefg,起始位置为 3,结束位置为 5,则剪贴操作后, 剪贴板内容为 cde,操作后字符串变为 abfg。字符串位置从 1 开始编号。
粘贴:给定插入位置的前后字符串,寻找到插入位置,将剪贴板内容插入到位置中,并清除剪贴板内容。例如,对于上面操作后的结果,给定插入位置前为 bf,插入位置后为 g,则插入后变为 abfcdeg。如找不到应该插入的位置,则直接将插入位置设置为字符串最后,仍然完成插入操作。查找字符串时区分大小写。
每次操作后的字符串即为新的当前字符串。在若干次操作后,请给出最后的编辑结果。

输入格式:
输入第一行是一个长度小于等于 200 的字符串 S,表示原始字符串。字符串只包含所有可见 ASCII 字符,不包含回车与空格。

第二行是一个正整数 N (1≤N≤100),表示要进行的操作次数。

接下来的 N 行,每行是两个数字和两个长度不大于 5 的不包含空格的非空字符串,前两个数字表示需要剪切的位置,后两个字符串表示插入位置前和后的字符串,用一个空格隔开。如果有多个可插入的位置,选择最靠近当前操作字符串开头的一个。

剪切的位置保证总是合法的。

输出格式:
输出一行,表示操作后的字符串。

输入样例:
AcrosstheGreatWall,wecanreacheverycornerintheworld
5
10 18 ery cor
32 40 , we
1 6 tW all
14 18 rnerr eache
1 1 e r

输出样例:
he,allcornetrrwecaneacheveryGreatWintheworldAcross

以下是我个人写的代码

#define   _CRT_SECURE_NO_WARNINGS  1
#include<stdio.h>
#include<string.h>
#define MAX 201


void Cuts(char s[MAX], char temp[MAX], int left, int right, int* len)
{
    int i;
    int length = right - left + 1;
    for (i = 0; i < length; i++)
    {
        temp[i] = s[i + left - 1];
    }
    //左移
    while (s[right] != '\0')
    {
        s[left - 1] = s[right];
        left++;
        right++;
    }
    s[left - 1] = '\0';
    (*len) -= length;
}

void Paste(char s[MAX], char temp[MAX], char arr1[6], char arr2[6], int len, int lenarr1, int length)
{
    int flag = 0;
    int i;
    int temp1 = len;
    char* p1 = s;
    char* p2 = NULL;
    while (1)
    {
        p1 = strstr(p1, arr1);
        if (p1 != NULL)
        {
            p2 = strstr(p1, arr2);
            if (p2 == NULL)
            {
                //如果没找到,就把要粘贴的内容放在最后
                p2 = s + len;
                for (i = 0; i < length; i++)
                {
                    *p2 = temp[i];
                    p2++;
                }
                *p2 = '\0';
                break;
            }
            if (p2 - p1 == lenarr1)
            {
                //粘贴操做
                while (&(s[temp1]) - p2 >= 0)
                {
                    s[temp1 + length] = s[temp1];
                    temp1--;
                }
                for (i = 0; i < length; i++)
                {
                    *p2 = temp[i];
                    p2++;
                }
                break;
            }
            else
            {
                //例如cdabcdmn,如果想要寻找的是cd mn 那么第一次找的cd是开头的
                //而并非与mn相邻的满足要求的cd,所以p1向后挪动一个字节重新寻找
                p1++;
            }

        }
    }
}

void Init(char temp[MAX], int length)
{
    int i;

    for (i = 0; i < length; i++)
    {
        temp[i] = 0;
    }
}
int main()
{
    char s[MAX] = { 0 };    //初始的输入数组
    char arr1[6] = { 0 };    //arr1表示要插入的前字符串
    char arr2[6] = { 0 };    //arr2表示要插入的后字符串
    char temp[MAX] = { 0 };    //剪切板
    int N;
    int i;
    int len, lenarr1;        //len-s的长度  lenarr1--arr1长度
    int left, right;        //表示要剪切的左边、右边
    int length;
    scanf("%s", s);
    scanf("%d", &N);

    for (i = 0; i < N; i++)
    {
        len = strlen(s);
        scanf("%d %d %s %s", &left, &right, arr1, arr2);
        lenarr1 = strlen(arr1);
        //剪切
        //把s的第left到right的元素从s上剪切下来保存至检测版temp中
        Cuts(s, temp, left, right, &len);
        length = right - left + 1;
        //粘贴
        Paste(s, temp, arr1, arr2, len, lenarr1, length);
        Init(temp, length);
    }
    printf("%s", s);
}


img

按照题目给出的例子,我的这个程序结果是正确的,就是老是会报段错误,不明白那里的问题。恳请大家帮忙改正,再次致谢!

OpenClipboard
EmptyClipboard
GlobalAlloc
GlobalLock
GlobalUnlock
CloseClipboard

【以下回答由 GPT 生成】

代码中可能出现段错误的原因是在剪切和粘贴操作中,temp数组的长度可能会超过其定义的长度MAX。这是因为temp数组用于存储剪切的部分字符串和粘贴的辅助字符串,在复制的过程中可能会超出MAX的范围导致内存溢出。

为了解决这个问题,可以在定义temp数组时将数组长度增加到len的两倍,即如果len最大为200,那么temp数组的长度应该为400。这样就可以确保在剪切和粘贴操作中不会超出temp数组的范围。

修改后的代码如下:

#define   _CRT_SECURE_NO_WARNINGS  1
#include<stdio.h>
#include<string.h>
#define MAX 400

void Cuts(char s[MAX], char temp[MAX], int left, int right, int* len)
{
    int i;
    int length = right - left + 1;
    for (i = 0; i < length; i++)
    {
        temp[i] = s[i + left - 1];
    }
    //左移
    while (s[right] != '\0')
    {
        s[left - 1] = s[right];
        left++;
        right++;
    }
    s[left - 1] = '\0';
    (*len) -= length;
}

void Paste(char s[MAX], char temp[MAX], int left, int right, int* len)
{
    int i, j;
    int length = right - left + 1;
    for (i = 0; i < *len; i++)
    {
        temp[length + i] = s[left + i - 1];
    }
    for (i = 0; i < length; i++)
    {
        s[left + i - 1] = temp[i];
    }
    s[left + length - 1] = '\0';
    (*len) += length;
}

int main()
{
    char s[MAX];
    char temp[MAX];
    int len, left, right, n;
    scanf("%s", s);
    len = strlen(s);
    scanf("%d", &n);
    while (n--)
    {
        scanf("%d%d%s%s", &left, &right, temp, temp);
        Cuts(s, temp, left, right, &len);
        scanf("%d%s%s", &left, temp, temp);
        Paste(s, temp, left, left + 1, &len);
    }
    printf("%s", s);
    return 0;
}

这样修改后的代码应该能够避免段错误的问题。如果还有其他问题,可以进一步调试以找到具体的问题所在。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^