如何在c中有效地解析字符串

时间:2011-07-29 01:27:50

标签: c string char

我有:

char *str = "abc def  abcdef ghi   xyz";

我想分配

const char *a = "abc"; 
const char *b = "def";
const char *c = "abcdef";
const char *d = "ghi";
const char *e = "xyz";

这里的关键是空格数可以多于一个。

请提出一个有效的方法。

5 个答案:

答案 0 :(得分:7)

效率是旁观者的眼睛。但是看看strtok;但是,您需要使用可以修改的字符串副本。

请注意,char *str = "blah"不是一个好主意。您应该使用const char *str = "blah"

答案 1 :(得分:5)

以下是使用strok_r的示例代码。它是strtok的可重入版本(不确定它是否是C标准的一部分)。另外,我假设你只有5个令牌。如果您想要更多,则必须使用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;
}

答案 2 :(得分:2)

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

但我会从for循环中调用strtok。

答案 3 :(得分:1)

strtok将多个连续空格视为单个分隔符,因此它可以解决您的问题

答案 4 :(得分:1)

对于空格分隔数据,您实际上可以在格式字符串中使用具有适当魔力的sscanf

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