raspiduino
raspiduino

Reputation: 681

Is there a C function for inserting/appending char* to an defined location in another char*?

I want to insert a char* to a defined location in another char*. For example:

char str1[80] = "Hello world!";
char str2[] = "the ";

I want the result to be Hello the world! (insert str2 to location 6 of str1)

I have tried:

#include <stdio.h>

char str1[80] = "Hello world!";
char str2[] = "the ";
char tmp1[80];
char tmp2[80];

char *string_insert(char *scr, char *ins, int loc){
    // Get the chars from location 0 -> loc
    for(int i = 0; i <= loc; i++){
        tmp1[i] = scr[i];
    }
    
    // Get the chars from loc -> end of the string
    for(int i = 0; i < sizeof(scr) - loc; i++){
        tmp2[i] = scr[i + loc];
    }
    
    // Insert the string ins
    for(int i = 0; i < sizeof(ins); i++){
        tmp1[i + loc] = ins[i];
    }
    
    // Add the rest of the original string
    for(int i = 0; i < sizeof(scr) - loc; i++){
        tmp1[loc + 1 + i] = tmp2[i];
    }
    
    return tmp1;
}

int main(){
    printf("%s", string_insert(str1, str2, 6));
    return 0;
}

But then I got Hello two. You can execute it online at onlinegdb.com

I also wonder if there is any function from string.h that can do this?

Thanks for any help!

Upvotes: 0

Views: 82

Answers (3)

Clifford
Clifford

Reputation: 93476

There is no string insert function. There is a strcat() function which appends. Implementing your own however is simple enough using the string primitives that are available:

char* string_insert( char* scr, const char* ins, size_t loc )
{
    size_t ins_len = strlen(ins) ;
    strcpy( &scr[loc + ins_len], &scr[loc] ) ;
    memcpy( &scr[loc], ins, ins_len ) ;
    return scr ;
}

Here the end of the string is moved to make space for ins, then ins copied to the gap.

Example usage:

int main()
{
    char str1[80] = "Hello world!" ;
    const char* str2 = "the " ;
    printf( "%s\n", string_insert( str1, str2, 6 ) ) ;

    return 0;
}

The insertion is done in place and directly modifies scr so needs no destination buffer. That would be the idiomatic behaviour given the interface the you have specified. The use of the global tmp1 and tmp2 arrays in your attempt are not good practice, and entirely unnecessary (as is always the case with globals). If you do want to modify a separate destination string (so scr is const), then you should pass that buffer as an argument:

char* string_insert( const char* scr, const char* ins, size_t loc, char* dest )
{
    size_t ins_len = strlen(ins) ;
    memmove( dest, scr, loc ) ;
    strcpy( &dest[loc + ins_len], &scr[loc] ) ;
    memcpy( &dest[loc], ins, ins_len ) ;
    return dest ;
}

int main()
{
    const char* str1 = "Hello world!";
    const char* str2 = "the " ;
    char str3[80] = "" ;
    
    printf( "%s\n", string_insert(str1, str2, 6, str3 ) ) ;

    return 0;
}

The use of const parameters allows string literals to be passed as arguments so for the first "in-place" version.:

char str[80] = "Hello world!" ;
printf( "%s\n", string_insert( str, "the ", 6 ) ) ;

And for the "destination buffer" version:

char str[80] = "" ;
printf( "%s\n", string_insert( "Hello world!", "the ", 6, str ) ) ;

Upvotes: 0

Remo.D
Remo.D

Reputation: 16512

There's no function in the standard library to insert a string into another.

You have to first create enough space for the characters you want to insert by moving the original characters to the right:

Hello World\0
Hello WorlWorld\0    <- move characters to the right
Hello the World\0   <- rewrite (including ' ')

In your example you have enough space (you create a buffer of 80 characters and use only 12 of them) but you should be absolutely be sure that this is the case.

However this is not what your code does. You copy those characters in another buffer and use that one as return value. In other words, your str1 is left unchanged. I don't think this is what you wanted, right?

Upvotes: 2

Iłya Bursov
Iłya Bursov

Reputation: 24146

fixed code with some comments to help with understanding:

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

char str1[] = "Hello world!"; // use `[]` to include trailing \0
char str2[] = "the ";

char tmp1[80]; // not very good idea to use global variables, but for algorithm learning purposes it is ok
char tmp2[80];

char *string_insert(char *src, char *str, int loc){
    // function uses global variable tmp1
    // if total length of string is > 80 - result is undefined
    
    int ti = 0; // index in tmp variable
    while (ti<loc) tmp1[ti++] = *src++; // copy first part from src
    while (*str) tmp1[ti++] = *str++; // append str
    while (*src) tmp1[ti++] = *src++; // append the rest of src

    tmp1[ti] = 0; // don't forget trailing 0
    return tmp1;
}

int main(){
    printf("%s", string_insert(str1, str2, 6));
    return 0;
}

Upvotes: 0

Related Questions