How do I split a string at an arbitrary index?
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)
{
c开发者_StackOverflow社区har *text ="Hello World."; /*12 C*/
char one[5];
char two[5];
char three[2];
return 1;
}
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 */
}
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.
精彩评论