0

我有一个如下所示的数据,它分别包含人名和年龄,她我只显示了 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 ....."
4

5 回答 5

1

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

于 2013-06-02T12:14:12.657 回答
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;
}
于 2013-06-02T13:24:36.317 回答
0

您可能想使用sscanf. 您需要%s人名和%d年龄的格式。

于 2013-06-02T12:11:44.287 回答
0

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

用strstr的指针p得到“Name”的位置,再往前5得到name的开始位置,然后strchr的指针q加上空格得到名字的结尾,然后你可以用snprintf的strncpy得到确切的名字

于 2013-06-02T12:32:29.857 回答
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
  }
}
于 2013-06-02T13:47:52.730 回答