开发者

how to efficiently parse a string in c

开发者 https://www.devze.com 2023-03-23 13:04 出处:网络
I have: char *str = \"abc defabcdef ghixyz\"; I want to assign const char *a = \"abc\"; const char *b = \"def\";

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;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消