【问题标题】:Insert a string inside of another string (without an intermediate string)在另一个字符串中插入一个字符串(没有中间字符串)
【发布时间】:2022-01-08 07:16:21
【问题描述】:

我遇到了这个问题,它询问是否可以编写函数

void insert(char* M, char* T, int i)

从索引 i 开始在 M 中插入字符串 T,而不使用中间字符串...我尝试使用 realloc 但我认为当原始字符串 M 比结果小很多时会出现问题,我的理论是realloc 更改了字符串的地址以能够表示新字符串。

例如:M="Wg" T="ron" and i=1;结果应该是 M="Wrong"。

我正在使用以下代码:

void insert(char* M,char* T,int i)
{
    int l;
    l=strlen(M);
    M=realloc(M,l+strlen(T)+1);

    for(int j = l-1; j >= i; j--)
    {
        M[j+strlen(T)]=M[j];
    }

    for(int j = 0;j < strlen(T); j++)
    {
        M[i+j]=T[j];
    }

    M[l+strlen(T)]='\0'; //from what i've tested the string M is correct.
}

并使用此声明:

    char *s=malloc(3);
    char *c=malloc(18);
    strcpy(s,"as");
    strcpy(c,"bcdefghijklmnopqr");
    insert(s,c,1); //this example does not work on my machine.

我希望这可以澄清问题。

那么有什么办法吗?

【问题讨论】:

  • man memmove ...
  • 如果您要使用realloc a) 传递的指针必须是动态分配的(例如,不是数组),并且 2) 您必须 return 重新分配的指针调用者。
  • 从编辑中,您将无法从 M = "Wg" 重新分配或插入任何内容。
  • @RafikBouloudene 如果内存管理的责任在调用者身上,那么insert 原型是可能的。请说明您遇到问题的部分。
  • 用另一种方式问,您是否在为组合字符串或实际组合字符串的算法分配足够空间时遇到问题?这是两个不同的问题。

标签: c string


【解决方案1】:

[这不是一个真正的答案;这是一个太复杂的说明,无法发表评论。]

如果你可以假设调用者看起来像

char string[6] = "Wg";
insert(string, "ron", 1);

(或者string数组的大小大于5),那么您可以轻松编写insert()

如果你可以假设调用者看起来像

char *string = malloc(3);
strcpy(string, "Wg");
insert(string, "ron", 1);

那么您几乎可以使用realloc 编写insert() 以使字符串更大,除非您无法返回string 的可能新(即可能移动)值。

如果调用者看起来像

char *string = "Wg";
insert(string, "ron", 1);

甚至

char *string = "Wg\0\0\0";
insert(string, "ron", 1);

你绝对不能写insert(),因为你不能假设指向的字符串是可写的(在许多平台上它不会)。

所以,一般来说,答案是:“不”。您无法编写在所有情况下都可以使用的通用版insert()

还要注意,如果您假设字符串在 malloc'ed 内存中并且您可以使用 realloc(如在我的第二个示例中),那么该代码将工作对于没有 malloc 的字符串(也就是说,它不适用于像我的第一个示例那样的调用者),并且根据传递给它的指针,它没有可移植的方式知道是否可以安全使用realloc 与否。

【讨论】:

    【解决方案2】:

    使用memmove 的可能实现示例。说明在 cmets 中

    #include <stdio.h>
    #include <string.h>
    
    void insertString(char* M, const char* T, size_t index)
    {
        // ASSUMES there's enough space in M for this operation
        // get the original lengths of each string
        size_t Mlen = strlen(M);
        size_t Tlen = strlen(T);
    
        if (index < Mlen)
        {
            // M+index+Tlen is the destination position where the remaining characters in M will start
            // M+index is the index where T will be inserted
            // Mlen-index is the remaining number of characters in M that need to move
            memmove(M+index+Tlen, M+index, Mlen-index);
            // copy the T string to the space we just created
            memcpy(M+index, T, Tlen);
            // NUL terminate the new string
            M[Mlen + Tlen] = '\0';
        }
        else
        {
            // simply strcat if the index falls outside the range of M
            strcat(M, T);
        }
    }
    

    如果不允许您使用memmovememcpy,您可以自己滚动。

    Demo

    【讨论】:

      猜你喜欢
      • 2015-02-11
      • 1970-01-01
      • 2015-04-04
      • 2011-05-13
      • 2012-09-25
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      相关资源
      最近更新 更多