解析所需值的字符串

时间:2013-06-02 12:10:05

标签: c string

我有一个如下所示的数据,它分别包含人名和年龄,她我只显示了3个人的名字和相应的年龄,我也可以在该字符串中有多个具有相应年龄的名字。

我想解析这个字符串并将名称和相应的年龄存储在一个结构中,请你告诉我如何解析这个名字和年龄。例如:我想得到Allan 35并将其分别存储在名称和年龄字段的下面结构中。来自该字符串中的所有名称。 如何解析字符串,我尝试了strstr()但它对我没用。请任何人都可以告诉如何解析这个字符串。

struct data_base{
  char *name;
  int age;
  };

char data[] = "Name Allan Age 35 Name John Age 50 Name Jim Age 20 ....."

5 个答案:

答案 0 :(得分:1)

您可以使用strtok来提取令牌。

答案 1 :(得分:1)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct data_base{
  char *name;
  int age;
};

#define NAME_TAG "Name "
#define AGE_TAG "Age "

char* getName(char **p){
    int tag_size = strlen(NAME_TAG);
    if(strncmp(*p, NAME_TAG, tag_size)==0){
        char *agep = strstr(*p += tag_size, AGE_TAG);
        int len = agep - *p -1;//-1: for space before "Age"
        char *name = calloc(len + 1, sizeof(char));
        strncpy(name, *p, len);
        *p = agep;
        return name;
    }
    return NULL;
}

int getAge(char **p){
    int tag_size = strlen(AGE_TAG);
    if(strncmp(*p, AGE_TAG, tag_size)==0){
        int age = (int)strtol(*p += tag_size, p, 10);
        if(**p == ' ')
            *p += 1;
        return age;
    }
    return -1;
}

struct data_base *parse(char *data, size_t *size){
    char *p = data;
    struct data_base *dbp=NULL;
    *size = 0;
    while(*p){
        *size += 1;
        dbp = realloc(dbp, sizeof(struct data_base)*(*size));
        dbp[*size -1].name = getName(&p);//this is treated as format is correct
        dbp[*size -1].age  = getAge(&p);
    }
    return dbp;//realloc(dbp, sizeof(struct data_base)*(*size));
}

int main(void){
    char data[] = "Name Allan Age 35 Name John Age 50 Name Jim Age 20";
    struct data_base *dbp;
    size_t i, size;

    dbp = parse(data, &size);
    //check print
    for(i = 0; i < size ;++i){
        printf("Name: %s, Age: %d\n", dbp[i].name, dbp[i].age);
    }
    //deallocate
    return 0;
}

答案 2 :(得分:0)

您可能想要使用sscanf。您的姓名需要%s格式,年龄需要%d

答案 3 :(得分:0)

你可以使用两个指针来获取单词的开头和结尾,

使用指针p通过strstr获取“Name”的位置,然后前面5来获取名称的起始位置,然后指针q通过strchr用空格来获取名称的结尾,那么你可以使用strncpy of获取确切名称的snprintf

答案 4 :(得分:0)

使用sscanf()创建处理每条记录的功能。

// Scan string, return >0 if successful, 0 if done, else error code
int JZ_ScanDB(const char *data, int *Index, struct data_base *Dest) {
  if (Dest) {
    Dest->age = 0;  // Form default answer
    Dest->name = 0;
  }
  if (!data || !Index || !Dest) return -1;  // Gremlins in your code
  if ((*Index < 0) || (*Index > strlen(data))) return -2; // More gremlins
  if (data[*Index] == '\0') return 0; // we are done
  char Name[1000];
  int retval = sscanf(&data[*Index], "Name %s Age %d %n", Name, &Dest->age, Index);
  if (retval != 2) {
    return -3;
  }
  Dest->name = strdup(Name);
  return 0;
}

void DoIt() {
  char data[] = "Name Allan Age 35 Name John Age 50 Name Jim Age 20";
  int i = 0;
  struct data_base Person;
  int ret;
  while ((ret = JZ_ScanDB(data, &i, &Person)) > 0) {
    // do something with Person, watch for memory management
    }
  if (ret) {
    // deal with unusual reason for stopping
  }
}