Reputation: 23
If I have this code:
int main ()
{
char *sentence = "Wisteria#Tunnel";
char stringA[50];
char stringB[50];
char stringC[50];
pDelim = strstr(sentence,"#");
*pDelim = '\0';
strcpy(stringA,sentence);
strcpy(stringB,(pDelim+1));
return(0);
}
After running it, stringA
will be "Wisteria" and stringB
will be "Tunnel", right?
If :
char *sentence = "Wisteria#Tunnel#Japan";
How to extracted it to three part , stringA
will be "Wisteria" , stringB
will be "Tunnel" and stringC
will be "Japan"
Thanks.
Upvotes: 0
Views: 481
Reputation: 20878
For anything more complicated, using strtok
is the way to go, but you can use strstr
. I didn't bother to copy the resultant substrings to new strings, but just printed them to the console. If you wanted to save them, you could either save all of the b
pointers to an array, or use strcpy
to make copies.
#include <stdio.h>
#include <string.h>
int main ()
{
char *sentence = "Wisteria#Tunnel#foo#bar";
char* b = sentence;
while(1) {
char*a = strstr(b,"#");
if (a) *a = 0;
printf("%s\n",b);
if (!a) break;
b = a+1;
}
}
Output is
Wisteria
Tunnel
foo
bar
Upvotes: 0
Reputation: 22478
Standard string functions strtok
, strstr
, strchr
all will work, provided the surrounding code is correct as well. That is, if you want to search multiple times in the same source string, you need to point a Start-at pointer at the start of your source, and after each (succesful!) search update it to point after your delimiter. By default, strtok
will work fine for your purpose -- a single character delimiter. You can read about strtok
in any good reference (I'm not going to look it up for you).
In fact it is such a simple operation, I made this up just now. Other than vanilla strtok
, my strcpyUpTo
accepts any delimiter string. I could have used strstr
to first check, but I prefer copying right away. The strncmp
and strlen
inside the copy loop may be inefficient; then again, in general these low-level string operations should be pretty fast nevertheless.
#include <stdio.h>
#include <string.h>
char *strcpyUpTo (const char *source, char *dest, const char *delim)
{
while (*source && strncmp (source, delim, strlen(delim)))
*dest++ = *source++;
*dest = 0;
if (*source)
return (char *)(source+strlen(delim));
return (char *)source;
}
int main (void)
{
char *sentence = "Wisteria#any#Tunnel#any#Japan";
char stringA[50];
char stringB[50];
char stringC[50];
char *pDelim;
pDelim = strcpyUpTo (sentence, stringA, "#any#");
pDelim = strcpyUpTo (pDelim, stringB, "#any#");
pDelim = strcpyUpTo (pDelim, stringC, "#any#");
printf ("stringA = \"%s\"\n", stringA);
printf ("stringB = \"%s\"\n", stringB);
printf ("stringC = \"%s\"\n", stringC);
return 0;
}
For an unknown number of substrings, you can use a while
loop such as the following. (For production code, it needs all kinds of checks. Left out for brevity, for clarity, and as exercise for the reader.) It's basically how you'd use strtok
as well.
char resultList[10][50];
int i, n_result;
pDelim = sentence;
n_result = 0;
do
{
pDelim = strcpyUpTo (pDelim, resultList[n_result], "#any#");
n_result++;
} while (*pDelim && n_result < 10);
printf ("number of strings: %d\n", n_result);
for (i=0; i<n_result; i++)
printf ("string %d = \"%s\"\n", i, resultList[i]);
Upvotes: 1
Reputation: 40145
#include <stdio.h>
int main (){
char *sentence = "Wisteria#Tunnel#Japan";
char stringA[50];
char stringB[50];
char stringC[50];
sscanf(sentence, "%49[^#]#%49[^#]#%49[^#]", stringA, stringB, stringC);
puts(stringA);puts(stringB);puts(stringC);
return(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **split(const char *str, char delimiter){
char **words = malloc(sizeof(char*));
const char *p = str;
int wc = 0;
for(;;){
char *pos;
int len;
if((pos = strchr(p, delimiter))!=NULL){
len = pos - p;
words[wc] = malloc(len+1);
strncpy(words[wc], p, len);
words[wc][len] = '\0';
words=realloc(words, (++wc+1)*sizeof(char*));
} else {
pos = strchr(p, '\0');
len = pos - p + 1;
words[wc] = malloc(len);
strncpy(words[wc], p, len);
words=realloc(words, (++wc+1)*sizeof(char*));
words[wc] = NULL;//End Mark
break;
}
p = pos + 1;
}
return words;
}
int main (){
char **sentences = split("Wisteria#Tunnel#Japan", '#');
int i;
for(i=0;sentences[i];++i){
puts(sentences[i]);
free(sentences[i]);
}
free(sentences[i]);
free(sentences);
return(0);
}
Upvotes: 0