读取C中具有特定结构的文件

时间:2013-04-19 04:01:11

标签: c fgets

我有一个格式如下的文件:

*Elset, elset = _121:0_125:0
1,
4,
6,
8,
*Elset, elset = _122:0
5,
7,
2,

在此文件中,“121:0”,“125:0”和“122:0”是每个图层的名称,后续数据集属于该图层。我需要做的是为每一层存储这些数据集。如果同时存在两个层,则意味着后续数据集属于它们。问题是我不知道有多少“Elset,elset = ...”,每层有多少数据。任何人都可以暗示一下吗?非常感谢。

2 个答案:

答案 0 :(得分:1)

*Elset, elset = _121:0_125:0
1,

您可以使用以下内容执行此操作:

char line[whatever_max];
int target[2000]; // track data set number to populate
int target_pos = 0;
while (fgets(line, whatever_max, fd))
{
    int lhs, rhs, total_chars_used, chars_used;
    if (sscanf(line, "*Elset, elset = _%d:%d%n", &lhs, &rhs, &total_chars_used) == 2)
    {
        // somehow, record lhs:rhs as a target data set being loaded...
        target_pos = 0;
        target[target_pos++] = lhs;
        target[target_pos++] = rhs;

        while (sscanf(line + total_chars_used, "_%d:%d%n",
                      &lhs, %rhs, &chars_used) == 2)
        {
            target[target_pos++] = lhs;
            target[target_pos++] = rhs;
            total_chars_used += chars_used;
        }
    }
    else if (sscanf(line, "%d,", &data) == 1)
         // add data to all current targets...
    else
        assert(!"unparsable line");
}

具体细节取决于您的数据集存储结构。

答案 1 :(得分:0)

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

typedef int Type;

#define INT 1
#define STR 2

typedef struct vector {
    Type type;
    size_t size;
    size_t capacity;
    void *array;
} Vector;

Vector *vec_make(Type type);
void vec_push(Vector* v, ...);
size_t vec_size(Vector *v);
void* vec_getArray(Vector *v);
void vec_drop(Vector *v);

typedef struct elset {
    Vector* layer;
    Vector* data;
} Elset;

#define RECORD_MAX 10

int main(void){
    Elset elset[RECORD_MAX];
    int input_count=-1;
    FILE *fp;
    char buff[1024];

    fp=fopen("data.txt", "r");
    while(fgets(buff, sizeof(buff), fp)){
        if(*buff == '*'){
            char *p;

            input_count += 1;//countup
            elset[input_count].layer = vec_make(STR);
            elset[input_count].data =vec_make(INT);
            for(p=strchr(buff, '_');p=strtok(p, "_\n");p=NULL){
                vec_push(elset[input_count].layer, strdup(p));
            }
        } else {
            vec_push(elset[input_count].data, atoi(buff));
        }
    }
    input_count += 1;
    fclose(fp);

    {   //check print
        int i, j, layerSize, dataSize;
        int *datas;
        char **layers;

        for(i=0;i<input_count;++i){
            layerSize=vec_size(elset[i].layer);
            layers=(char**)vec_getArray(elset[i].layer);
            for(j=0;j<layerSize;++j)
                printf("%s ", layers[j]);
            printf("\n");

            dataSize=vec_size(elset[i].data);
            datas=(int*)vec_getArray(elset[i].data);
            for(j=0;j<dataSize;++j)
                printf("%d ", datas[j]);
            printf("\n\n");
        }
        //deallocation
        for(i=0;i<input_count;++i){
            layerSize=vec_size(elset[i].layer);
            layers=(char**)vec_getArray(elset[i].layer);
            for(j=0;j<layerSize;++j)
                free(layers[j]);
            vec_drop(elset[i].layer);
            vec_drop(elset[i].data);
        }
    }
    return 0;
}

#define TypeSize(t) ((t == 1)? sizeof(int):sizeof(char*))

Vector *vec_make(Type type){
    Vector *v;
    v = (Vector*)malloc(sizeof(Vector));
    v->type = type;
    v->size = 0;
    v->capacity=4;
    v->array=realloc(NULL, TypeSize(type)*(v->capacity += 4));
    return v;
}

void vec_push(Vector* v, ...){
    va_list ap;

    va_start(ap, v);
    switch(v->type){
    case INT:
        ((int*)v->array)[v->size] = va_arg(ap, int);
        break;
    case STR:
        ((char**)v->array)[v->size] = va_arg(ap, char*);
        break;
    }
    va_end(ap);

    if(++v->size == v->capacity)
        v->array=realloc(v->array, TypeSize(v->type)*(v->capacity += 16));
}

size_t vec_size(Vector *v){
    return v->size;
}

void* vec_getArray(Vector *v){
    return v->array;
}

void vec_drop(Vector *v){
    free(v->array);
    free(v);
}