0

私は以下に示すようなデータを持っています。それにはそれぞれ人の名前と年齢が含まれています.彼女は3人の名前とそれぞれの年齢を示しています.

この文字列を解析して、名前と対応する年齢を構造体に保存したいのですが、この名前と年齢を解析する方法を教えてください。例: アラン 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

2 つのポインターを使用して、単語の開始と終了を取得できます。

strstr でポインター p を使用して「名前」の場所を取得し、次に 5 を使用して名前の開始位置を取得し、スペースを含む 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 に答える
0

を使用することもできますsscanf%s人の名前と%d年齢の形式が必要です。

于 2013-06-02T12:11:44.287 に答える