0

我正在尝试完成一项家庭作业,其中一部分是设计一个将字符串插入另一个字符串的函数。除了 strlen() 之外的所有函数对我来说都是禁区。具体来说,问题是:我无法实现在目标字符串中为插入的字符串“腾出空间”的函数部分。插入字符串总是会导致数组元素被践踏。谁能指出我在这里做错了什么?谢谢你帮助我学习!

编辑:整数 n 是我应该插入另一个字符串的字符串中的位置。

    void insertstring(char *str, char *ins, int n)
    {
        int i;
        int scoot=strlen(ins);
        char *p=str+n;

        for (i=strlen(str); i > n; --i) { //This is where I'm doing it wrong I think
            str[i+scoot]=str[i];          //
        }

        do {
            *p = *ins;
            ++p;
            ++ins;
        }
        while (*ins != '\0');
    }
4

4 回答 4

2

一个优雅的解决方案使用反转来实现所需的结果。假设您的目标字符串 str 由两个块 AB 组成,其中 A 是插入点之前的块,B 是插入点之后的块。此外,假设要插入的字符串 ins 由第三个块 C 表示。

可以看出,如果你将C连接到AB,然后反向B,反向C,同时反向B和C,得到ACB,这就是想要的结果。更明确地说,这是将 C 附加到 AB 之后的内容:

美国广播公司

这就是你想要的:

ACB

ACB 可以通过以下方式获得:

  • 反转B,得到B_r(B反转);
  • 反转C,得到C_r——此时我们有AB_rC_r;
  • 反转 B 和 C,即计算 A(B_rC_r)_r,得到 ACB。

下面是实现这个算法的代码:

void reverse(char *, char *, char *);
/* Insert string C between blocks AB in str */
void insertstring(char *str, char *ins, int n) {
    /* 1 - Append C to the end of str */
    int i = strlen(str);
    char *p = str+i, *q = ins;
    while ((*p++ = *q++));
    p--;
    /* 2 - Reverse C and B */
    reverse(str, str+i, p-1); /* C */
    reverse(str, str+n, str+i-1); /* B */
    /* 3 - Reverse B_rC_r */
    reverse(str, str+n, p-1);
}

void reverse(char *str, char *begin, char *end) {
    char tmp;
    while (begin < end) {
        tmp = *begin;
        *begin = *end;
        *end = tmp;
        begin++;
        end--;
    }
}

和一些示例代码来测试它:

#include <stdio.h>
#include <string.h>

int main() {
    void insertstring(char *, char *, int);
    char test[128] = "A string to test.";
    printf("Before: %s\n", test);
    insertstring(test, "hello!", 4);
    printf("After: %s\n", test);
    return 0;
}

这将插入“你好!” 从测试 [4] 开始。这是输出:

$ ./test
Before: A string to test.
After: A sthello!ring to test.

考虑采用这种方法:代码简短而优雅。此技术在 Programming Pearls,第 2 版中进行了描述,是一种执行矢量旋转的好方法。据作者介绍,Brian Kernighan 和 PJ Plauger 在他们的 Pascal 软件工具中正是使用这种方法在文本编辑器中移动行。

于 2013-10-09T12:35:13.050 回答
0

在提到 about 之后n,将 for 循环更新为

for (i=n+scoot; i >= n; i--)

您想strlen(ins)从 location 向前移动字符数n

于 2013-10-09T12:03:28.223 回答
0

首先你有零钱

for (i=strlen(str); i > n; --i)

for (i=strlen(str); i >= n; --i)

因为你也必须搬家str[n]

另一个问题是当您插入时ins

do {
        *p = *ins;
        ++p;
        ++ins;
}
while (*ins != '\0');

'\0'在这里,您将终止从复制ins到,str因此其余部分丢失。将其更改为

while (*ins != '\0') {
        *p = *ins;
        ++p;
        ++ins;
}
于 2013-10-09T12:06:19.430 回答
0

用单循环尝试过,

转到索引,将src内容复制到temp_array并同时复制medisrc 一次medi完全复制,开始放入内容temp_array直到它变空

void insert_in_middle (char *src, char *medi, int index)
{
    int i=0, j = index, k=0;
    char temp_array[50];

    while(src[j] != '\0' ||  temp_array[k] != '\0')
    {
        temp_array[i] = src[j];
        if(medi[i] != '\0')
        {
            src[j] = medi[i];
        }
        else if(temp_array[k] != '\0')
        {
            src[j] = temp_array[k];
            k++;
        }
        i++; j++;
    }
    printf("src[%s]\n", src);
    printf("medi[%s]\n",medi);
    printf("temp_array[%s]\n",temp_array);
}
于 2017-08-03T18:14:37.423 回答