Reputation: 25
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
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
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
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