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);
}
按照题目给出的例子,我的这个程序结果是正确的,就是老是会报段错误,不明白那里的问题。恳请大家帮忙改正,再次致谢!
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;
}
这样修改后的代码应该能够避免段错误的问题。如果还有其他问题,可以进一步调试以找到具体的问题所在。
【相关推荐】