stanlopfer
stanlopfer

Reputation: 73

How can I copy part of a string into another string?

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

void main(int ac, char *av[])
{
    char str1[] = "this is a test";
    char str2[20];
    char str3[30];
    strncpy(str2, str1, 5);
}

I want to copy five characters of string str1 into str2 starting at index 0 of string str1, then copy five characters of string str1 into str2 starting at index 1 of string1, and so on.

For example, the first str2 should be "this ". The second str2 = "his i". The third str2 "is is". How can I do this?

Upvotes: 1

Views: 30561

Answers (3)

David C. Rankin
David C. Rankin

Reputation: 84579

What you are attempting to do requires paying careful attention to your string indexes and pointer offsets. It isn't difficult, but if you attempt to read/write out of bounds, you immediately enter undefined behavior. The example below provides output showing what is taking place, so you can visually see the process.

I wasn't entirely clear on your exact purpose or what you intended to do with str3, but regardless, the following principles apply:

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

int main()
{
    char str1[] = "this is a test";
    char str2[20] = {0};                        /* always initialize variables  */
    // char str3[30] = {0};

    size_t i = 0;
    char p = 0;                                 /* temp char for output routine */

    for (i = 0; i < strlen (str1) - 4; i++)     /* loop through all chars in 1  */
    {                                           /* strlen(str1) (- 5 + 1) = - 4 */
        strncpy (str2+i, str1+i, 5);            /* copy from str1[i] to str2[i] */

        /* all code that follows is just for output */
        p = *(str1 + i + 5);                    /* save char at str1[i]         */
        *(str1 + i + 5) = 0;                    /* (temp) null-terminate at i   */
        /* print substring and resulting str2 */
        printf (" str1-copied: '%s' to str2[%zd], str2: '%s'\n", str1+i, i, str2);
        *(str1 + i + 5 ) = p;                   /* restor original char         */
    }

    return 0;
}

Output:

$ ./bin/strpartcpy
 str1-copied: 'this ' to str2[0], str2: 'this '
 str1-copied: 'his i' to str2[1], str2: 'this i'
 str1-copied: 'is is' to str2[2], str2: 'this is'
 str1-copied: 's is ' to str2[3], str2: 'this is '
 str1-copied: ' is a' to str2[4], str2: 'this is a'
 str1-copied: 'is a ' to str2[5], str2: 'this is a '
 str1-copied: 's a t' to str2[6], str2: 'this is a t'
 str1-copied: ' a te' to str2[7], str2: 'this is a te'
 str1-copied: 'a tes' to str2[8], str2: 'this is a tes'
 str1-copied: ' test' to str2[9], str2: 'this is a test'

Upvotes: 0

hcf
hcf

Reputation: 148

Just add your offset to the str1 argument of the strncpy call. For example:

strncpy(str2, str1 + 1, 5);

will copy five bytes into str2 from str1 starting at index 1.

Upvotes: 4

Vlad from Moscow
Vlad from Moscow

Reputation: 311068

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

int main()
{
     char str1[] = "this is a test";
     char str2[20];
     char str3[30];

     strncpy( str2, str1, 5 );
     str2[5] = '\0';
     strncpy( str3, str1 + 1, 5 );
     str3[5] = '\0';

     //...
}

Here is a more complete example

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

int main()
{
    char str1[] = "this is a test";
    char str2[sizeof( str1 ) - 5][6];
    const size_t N = sizeof( str1 ) - 5;
    size_t i;

    for ( i = 0; i < N; i++ )
    {
        strncpy( str2[i], str1 + i, 5 );
        str2[i][5] = '\0';
    }

    for ( i = 0; i < N; i++ )
    {
        puts( str2[i] );
    }

    return 0;
}

The output is

this 
his i
is is
s is 
 is a
is a 
s a t
 a te
a tes
 test

Upvotes: 1

Related Questions