Morde
Morde

Reputation: 25

Spilt a string into half and join it with another string

I wanna ask if say i have a string "abcdefgh" and I want to half it to become "abcd" and "efgh" and store it into their own strings say I call it "UpperHalf" and "LowerHalf". So the way to do this is to first make use of the strlen() to find out the length of my input and half it? Then I would need to use strcpy() and copy it to their respective strings right?

Actually I don't even know if my code makes any sense. Anyone can give me some comments on it?

I realized I only need to consider even input numbers which means I do not need to worry about odd inputs. Previously I was trying to spilt a 1d string into half and then strcat it with something else. But now I am given a series of input strings that are stored in 2d array format. In this case, how do I retrieve these strings and manipulate them as though it is the same as the previous 1d case? I don't think I need to use for loops? Can I just point to the row?

int d = strlen(str); // just an example where str = the characters inside my string
strcpy(temp, &str[0]); // store original string into a temp string starting from 0 to \0
str[d/2] = '\0';
strcpy(UpperHalf, &str[0]); // starts copying from position 0 to \0 which is the half way point
str[0] = temp;  //revert back to normal -> Does this line even make sense?
strcpy(LowerHalf, &str[d/2]);

Upvotes: 1

Views: 721

Answers (3)

David C. Rankin
David C. Rankin

Reputation: 84579

While it is fine to use all the standard functions to copy the lower/upper halves to separate strings, you can also split the string using only pointers and a separate buffer to hold the lower-half of the string.

Basically, you can find the length of the string, adjust the odd/even location of the midpoint (if desired to always but the additional char on odd lengths in the lower-half), and then use a simple loop to copy to lower-half. At the end of the loop, the pointer used points to the upper-half (or you can simply use the pointer for the location of the midpoint). A short example would be:

#include <stdio.h>

#define MAXC 64

int main (int argc, char **argv) {

    if (argc < 2 ) {
        fprintf (stderr, "error: insufficient input, usage: %s string\n",
                argv[0]);
        return 1;
    }

    char lower_half[MAXC] = {0};    /* array to hold lower_half */
    char *p = argv[1];              /* poiter to string         */
    char *pl = lower_half;          /* pointer to lower_half    */
    char *split = NULL;             /* pointer to split point   */
    size_t len = 0;                 /* string length            */

    for (; *p; p++);        /* find end of string   */
    len = p - argv[1];      /* get string length    */
    p = argv[1];            /* reset pointer        */
    split = p + len/2;      /* set split at middle  */
    if (len & 1) split++;   /* if odd, add 1        */

    for (; p < split; p++)  /* for each ch < split  */
        *pl++ = *p;         /* copy to lower_half   */
    *pl = 0;                /* null-terminate       */

    /* print results */
    printf ("\n lower_half : '%s'    upper_half : '%s'\n",
            lower_half, split);

    return 0;
}

Output

$ ./bin/str_half 123456789

 lower_half : '12345'    upper_half : '6789'

$ ./bin/str_half 1234567890

 lower_half : '12345'    upper_half : '67890'

Regardless of whether you use pointers or use strlen, strncpy, or memcpy, etc., just be sure you null-terminate the separated strings. Above, the explicit null-termination is not required due to lower_half being initialized to all 0 at the beginning. However, it is good practice to always insure your code is null-terminating your strings.

Upvotes: 0

PeteB
PeteB

Reputation: 372

Yes you definitely need to consider the odd number string lengths. There are code approaches which will either round it up or down (so that the first or second string will have the extra character) but you need to decide which way you want it to go.

Looking at your code, I would suggest that using the temp string is not needed. You can copy directly from the original 'str' and save that memory and processor overhead. A few changes will be needed: Currently you're overwriting one of the characters in your source string with the '\0' character, and your second strcpy is starting at that '\0' which will return a zero length string. To copy a fixed number of characters, you can use strncpy which will work better here than strcpy by simplifying your code and keeping things clear. Don't forget to terminate your strings with a \0, or you could initialise the buffers with 0 values as I have here.

So, an example might look like this:

char UpperHalf[MAX_LENGTH];
char LowerHalf[MAX_LENGTH];

int l = strlen(str);
int half = l / 2;
memset(LowerHalf, '\0', MAX_LENGTH);
strncpy(LowerHalf, str, half);
memset(UpperHalf, '\0', MAX_LENGTH);
strncpy(UpperHalf, str + half, l - half);

This will put the longer part of an odd length string into the UpperHalf char array. To make the code safe you should also consider doing length comparisons to ensure that all strings will fit in the buffers provided (with at least one character left over for the string terminating \0 character).

Upvotes: 1

Jon Purdy
Jon Purdy

Reputation: 55039

Yes, you must first use strlen to get the length of the input string, and halve it to give the length of upper_half:

size_t length = strlen(str);
size_t upper_length = length / 2;
size_t lower_length = length - upper_length;

In this case, if the length of the input string is odd, then due to integer division, upper_length will equal lower_length - 1, e.g.:

length == 3
upper_length == 3 / 2 == 1
lower_length == 3 - 1 == 2

It’s easier to do the actual copying without modifying the original string, as your code is doing.

You must allocate space to store the copies of the string halves, with null terminators:

char *upper_half = malloc(upper_length + 1);
char *lower_half = malloc(lower_length + 1);

Then use memcpy to copy the string data:

memcpy(upper_half, &str[0], upper_length);
upper_half[upper_length] = '\0';

(Similarly for lower_half.)

strcpy copies characters until a null byte, while memcpy copies a given number of bytes.

Upvotes: 0

Related Questions