tags:

views:

77

answers:

2

How can I split up a string into pieces? For example, how can I place "orld." into a variable called one, "Hello" into a variable called three, and " w" into two?

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

int main(void)
{
    char *text ="Hello World."; /*12 C*/

    char one[5];
    char two[5];
    char three[2];

    return 1;
}
+1  A: 

First, you need to change one, two, and three from char to pointer to char or array of char -- a char holds only a single character, not a string of them.

Assuming you use pointer to char, you could do something like this:

#include <string.h>
#include <stdlib.h>

char *substr(char const *input, size_t start, size_t len) { 
    char *ret = malloc(len+1);
    memcpy(ret, input+start, len);
    ret[len]  = '\0';
    return ret;
}

int main() { 
    char *text = "Hello World.";
    char *one = substr(text, 7, 4);
    char *two = substr(text, 5, 2);
    char *three = substr(text, 0, 5);

    printf("\"%s\"\t\"%s\"\t\"%s\"\n", one, two, three);

    free(one);
    free(two);
    free(three);

    return 0;
}

Note that this allocates memory for the substring dynamically. It's up to the caller to free the string when it's no longer needed. Also note that I've omitted error checking for the sake of simplicity and clarity. For real code, you want the check that malloc returned a valid (non-null) pointer before you copy data there.

Jerry Coffin
This is a clean answer, but if he's having problems with this question, then he is likely to have even more problems with dynamically allocated memory. I still upvoted, though.
Merlyn Morgan-Graham
+1  A: 

For one, you cannot do what you asked, and still have them work as null-terminated strings. This is because the memory layout of text looks like this:

char text_as_array[] = {
  'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '.', '\0'
};

Notice the '\0' at the end. The character array test is not actually length 12, it is length 13.

Null-termination is required for console output functions, like printf and std::cout (C++) to work:

char good[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
printf("%s\n", good); /* this works, because it is null-terminated */

char bad[] = { 'H', 'e', 'l', 'l', };
printf("%s\n", bad); /* this will print out garbage, or crash your program! */

This means that you must define your arrays like this:

char one[6];
char two[3];
char three[6];

You can do this by hand by simply copying the values out:

one[0] = text[7]; /* o */
one[1] = text[8]; /* r */
one[2] = text[9]; /* l */
one[3] = text[10]; /* d */
one[4] = text[11]; /* . */
one[5] = '\0'; /* you have to null-terminate the string */

If you want to do less typing, or simply want to write better code, you can take advantage of the fact that arrays/strings are contiguous, and use a loop to copy that data over:

for(int i = 0; i < 5; ++i)
{
  one[i] = text[7 + i];
}
one[5] = '\0';

But if you guess that this is a really common thing to do in C, then you guess right. Instead of manually coding this loop each time, you should use a built-in function to do the copying for you:

/* C uses "", C++ uses <> */
#include "string.h" /* C++: #include<cstring> */
#include "stdio.h" /* C++: #include<cstdio> */

/* don't do "int function(void)", do "int function()" instead */
int main()
{
  char *text = "Hello World."; /* string length 12, array size 13 */

  /* size of these has to accomodate the terminating null */
  char one[6];
  char two[3];
  char three[6];

  /* copy two characters, starting at index 5 */
  strncpy(two, &text[5], 2);

  /* for three, we don't have to do &text[0], because it is at the beginning of the string */
  strncpy(three, text, 5);

  /* we can do strcpy if we're at the end of the string.  It will stop when it hits '\0' */
  strcpy(one, &text[7]);

  /* note that we still have to null-terminate the strings when we use strncpy */
  two[2] = '\0';
  three[5] = '\0';

  /* but we don't have to null-terminate when we use strcpy */
  /* so we can comment this out: one[5] = '\0'; */

  printf("%s\n", one);
  printf("%s\n", two);
  printf("%s\n", three);

  return 0; /* returns 0, since no errors occurred */
}
Merlyn Morgan-Graham