简体   繁体   中英

Insert a string inside of another string (without an intermediate string)

I came across this question and it asks if it's possible to write the function

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

that inserts the string T inside M starting from the index i, without using an intermediate string... I tried to use realloc but I think there's a problem when the original string M is a lot smaller than the result, my theory is that realloc changes the address of the string to be able to represent the new string.

For example: M="Wg" T="ron" and i=1; the result should be M="Wrong".

I'm using the following code:

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.
}

and using this declaration:

    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.

I hope this clarifies the question.

So is there a way to do it?

Example of a possible implementation using memmove . Explanations are in the comments

#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);
    }
}

If you're not allowed to use memmove or memcpy , it's simple enough to roll your own.

Demo

[This isn't really an answer; it's a clarification that's too complicated for a comment.]

If you can assume that the caller looks like

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

then you can write insert easily.

If you can assume that the caller looks like

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

then you can almost write insert using realloc , except you have no way to return the possibly-new value of string .

If the caller might look like

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

or even

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

than you cannot write insert() , because you cannot assume that the pointed-to string is writable (and on many platforms it will not be).

So, in general, no, you cannot write a version of insert that will work under all circumstances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM