how to efficiently parse a string in c
I have:
char *str = "abc def abcdef ghi xyz";
I want to assign
const char *a = "abc";
const char *b = "def";
const char *c = "abcdef";
const char *d = "ghi";
const char *e = "xyz";
Key here is that number of spaces can be more than one开发者_运维知识库.
Please suggest an efficient way.
Efficency is in the eye of the beholder. But take a look at strtok
; however, you will need to work with a copy of the string that can be modified.
Note that char *str = "blah"
is not a good idea. You should be using const char *str = "blah"
.
Here's some sample code using strok_r
. It is the re-entrant version of strtok
(not sure whether it is part of the C standard). Also, I've assumed that you only have 5 tokens. If you want to have more you'll have to modify the code to allocate additional memory using realloc
.
#include <string.h>
#include <stdio.h>
int main(void)
{
const char *str = "abc def abcdef ghi xyz";
char *dup = strdup( str );
char **output = malloc( 5 * sizeof(char *) );
char *p = dup;
char *nextp = NULL;
int i = 0;
if( dup == NULL ) {
// handle error
}
for( i = 0; i < 5; ++i ) {
output[i] = strtok_r( p, " ", &nextp );
p = NULL;
}
for( i = 0; i < 5; ++i ) {
printf( "output[%d] = %s\n", i, output[i] );
}
free( dup );
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
char *str = strdup("abc def abcdef ghi xyz");
char *a = strtok(str, " ");
char *b = strtok(NULL, " ");
char *c = strtok(NULL, " ");
char *d = strtok(NULL, " ");
char *e = strtok(NULL, " ");
printf("a=%s|b=%s|c=%s|d=%s|e=%s\n", a, b, c, d, e);
free(str);
return 0;
}
But I would call strtok from a for loop.
strtok
treats multiple contiguous spaces as a single delimiter so it should resolve your problem
For space delimited data, you can actually use sscanf
with appropriate magic in the format string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *str = "abc def abcdef ghi xyz";
// The simple example
char *a, *b, *c, *d, *e;
sscanf(str," %a[^ ] %a[^ ] %a[^ ] %a[^ ] %a[^ ]", &a, &b, &c, &d, &e);
// Dynamically constructing the format string and a char*[] of strings
enum { NVAR = 5 };
char **list;
char *fmtx = " %a[^ ]";
char *fmt;
int i;
list = malloc(NVAR*sizeof*list);
for (i=0; i < NVAR; i++) list[i] = malloc(sizeof**list);
fmt = malloc(NVAR*strlen(fmtx)+1);
fmt[0] = '\0';
for (i=0; i < NVAR; i++) strcat(fmt,fmtx);
sscanf(str,fmt,list,list+1,list+2,list+3,list+4,list+5);
for (i=0; i < NVAR; i++) if (list[i]) puts(list[i]);
return 0;
}
精彩评论