使用C动态字符串的文件解析问题

使用C动态字符串的文件解析问题,c,parsing,memory-management,c-strings,C,Parsing,Memory Management,C Strings,以下是需要解析的文件的一部分 record(ai, "SRC01-VA-IMG1:getPressure") { field(DESC, "Reads Cell SR-GC1 Pressure") field(SCAN, "1 second") field(DTYP, "stream") field(INP, "@vacuum-XGS600-gc.proto getPressure(1) SR-GC1") field(PINI, "YES") f

以下是需要解析的文件的一部分

record(ai, "SRC01-VA-IMG1:getPressure")
{
    field(DESC, "Reads Cell  SR-GC1 Pressure")
    field(SCAN, "1 second")
    field(DTYP, "stream")
    field(INP, "@vacuum-XGS600-gc.proto getPressure(1) SR-GC1")
    field(PINI, "YES")
    field(VAL, "0")
    field(PREC, "3")
    field(LOLO, "")     field(LLSV, "NO_ALARM")
    field(HIGH, "")     field(HSV,  "NO_ALARM")
    field(HIHI, "")     field(HHSV, "NO_ALARM")
}
解析过程将读取记录名称(在qoutes中)和类型(ai,在行记录中),以及每个字段类型和值(在以字段开头的任何行中,例如类型:PINI,值:“是”)。请注意,每行可以包含多个记录定义。该示例包含一些有趣的情况,如同一行上的多个字段、qoutes中的括号等

以下是我的代码:

struct field
{
    char* name;
    char* value;
};

struct record
{
    char* name;
    char* type;
    struct field* fields;
};

struct record* get_records(char* file, int* length)
{
    size_t SIZE = 0;
    size_t fSIZE = 1;
    const int N = 100;
    struct record* records = malloc(1 * sizeof(struct record));
    struct field* fields;
    // char line[N];
    char* line = malloc(N);
    char record_name[100];
    char record_type[10];
    char field_name[10];
    char field_value[100];
    char temp[100];

    int open, close, comma, q1, q2;
    FILE* fp = fopen(file, "r");
    if(fp != NULL)
    {
        while(fgets(line, N, fp))
        {
            line = strtrim(line);
            if(strncmp(line, "record", 6) == 0)
            {
                memset(record_name, 0, sizeof(record_name));
                memset(record_type, 0, sizeof(record_type));

                struct record* r = malloc(sizeof(struct record));
                open = strchr(line, '(') - line + 1;
                close = strchr(line, ')') - line + 1;
                comma = strchr(line, ',') - line + 1;
                q1 = strchr(line, '"') - line + 1;
                q2 = strrchr(line, '"') - line + 1;

                strncpy(record_type, &line[open], comma  - open - 1);
                strncpy(record_name, &line[q1], q2 - q1 - 1);
                record_name[q2 - q1 - 1] = '\0';
                record_type[comma  - open - 1] = '\0';
                r->name = record_name;
                r->type = record_type;

                printf("Name: %s\n", r->name);
                printf("Type: %s\n", r->type);

                fSIZE = 0;
                fields = malloc(100 * sizeof(field)); // HERE
                while(fgets(line, N, fp))
                {
                    struct field* f = malloc(sizeof(struct field));
                    if(strncmp(line, "}", 1) == 0)
                        break;

                    if(strncmp(line, "{", 1) == 0)
                        continue;

                    line = strtrim(line);
                    int i1 = 0;
                    int i2 = 0;
                    char* p1 = strstr(line, "field");
                    char* p2;
                    while(p1 != NULL)
                    {
                        i1 = p1 - line;
                        p2 = strstr(p1 + 1, "field");
                        if(p2 != NULL)
                        {
                            i2 = p2 - line;
                            p1 = strstr(p1 + 1, "field");
                        }
                        else
                        {
                            i2 = strlen(line);
                            p1 = NULL;
                        }

                        memset(temp, 0, sizeof(temp));
                        memset(field_name,  0, sizeof(field_name));
                        memset(field_value, 0, sizeof(field_value));

                        strncpy(temp, &line[i1], i2 - i1); temp[i2-i1] = '\0';
                        printf("Line2 : %s\n", temp);

                        open = strchr(temp, '(') - temp + 1;
                        close = strrchr(temp, ')') - temp + 1;
                        comma = strchr(temp, ',') - temp + 1;
                        q1 = strchr(temp, '\"') - temp + 1;
                        q2 = strrchr(temp, '\"') - temp + 1;

                        strncpy(field_value, &temp[q1], q2 - q1 - 1);         field_value[q2-q1-1] = '\0';
                        strncpy(field_name,  &temp[open], comma  - open - 1); field_name[comma-open-1] = '\0';

                        printf("Name : %s\n", field_name);
                        printf("Value: %s\n\n", field_value);

                        f->name = field_name;
                        f->value = field_value;

                        fields[fSIZE++] = *f;
                    }
                    free(line);
                    line = malloc(N);
                }
                r->fields = fields;
                records[SIZE++] = *r;
            }
            else
                continue;
        }
    }
    else
    {
        printf("%s\n", "Unable to open file.");
        exit(1);
    }

    *length = SIZE;
    // fclose(fp);
    return records;
}

int main()
{
    int length = 0;
    struct record* records = get_records("./test.db", &length);

    // printf("Anything \n");
    int i = 0;
    for(i = 0; i < length; i++)
    {
        struct record* r = (struct record*) &records[i];
        printf("Name: %s\n", r->name);
        printf("Type: %s\n", r->type);
    }
    return 0;
}
struct字段
{
字符*名称;
字符*值;
};
结构记录
{
字符*名称;
字符*类型;
结构字段*字段;
};
结构记录*获取记录(字符*文件,整数*长度)
{
大小\u t大小=0;
尺寸=1;
常数int N=100;
结构记录*记录=malloc(1*sizeof(结构记录));
结构字段*字段;
//字符行[N];
char*line=malloc(N);
字符记录_名称[100];
字符记录_类型[10];
字符字段_名称[10];
字符字段_值[100];
炭温度[100];
int打开、关闭、逗号、q1、q2;
文件*fp=fopen(文件“r”);
如果(fp!=NULL)
{
while(fgets(线路,N,fp))
{
line=strtrim(行);
if(strncmp(行,“记录”,6)==0)
{
memset(记录名称,0,大小(记录名称));
memset(记录类型,0,sizeof(记录类型));
结构记录*r=malloc(sizeof(结构记录));
open=strchr(行“(”)-行+1;
关闭=strchr(行“)”)-行+1;
逗号=strchr(第,,)行-第+1行;
q1=strchr(线“,”)-线+1;
q2=strrchr(行“,”)-行+1;
strncpy(记录类型和行[open],逗号-open-1);
strncpy(记录名称和行[q1],q2-q1-1);
记录名称[q2-q1-1]='\0';
记录类型[逗号-打开-1]='\0';
r->name=记录名称;
r->type=记录类型;
printf(“名称:%s\n”,r->Name);
printf(“类型:%s\n”,r->Type);
fSIZE=0;
fields=malloc(100*sizeof(field));//此处
while(fgets(线路,N,fp))
{
结构域*f=malloc(sizeof(结构域));
如果(strncmp(行“}”,1)==0)
打破
if(strncmp(行“{”,1)==0)
继续;
line=strtrim(行);
int i1=0;
int i2=0;
字符*p1=strstr(行,“字段”);
char*p2;
while(p1!=NULL)
{
i1=p1-线;
p2=strstr(p1+1,“字段”);
如果(p2!=NULL)
{
i2=p2-线;
p1=strstr(p1+1,“字段”);
}
其他的
{
i2=strlen(线);
p1=零;
}
memset(temp,0,sizeof(temp));
memset(field_name,0,sizeof(field_name));
memset(field_value,0,sizeof(field_value));
strncpy(temp,&行[i1],i2-i1);temp[i2-i1]='\0';
printf(“第2行:%s\n”,临时);
打开=strchr(温度“(”)-temp+1;
关闭=strrchr(温度“)”)-temp+1;
逗号=strchr(temp,,)-temp+1;
q1=strchr(温度“\”)-temp+1;
q2=strrchr(温度,“\”)-temp+1;
strncpy(字段_值,&temp[q1],q2-q1-1);字段_值[q2-q1-1]='\0';
strncpy(字段名,&temp[open],逗号-open-1);字段名[comma-open-1]='\0';
printf(“名称:%s\n”,字段名称);
printf(“值:%s\n\n”,字段值);
f->name=字段名称;
f->value=字段值;
字段[fSIZE++]=*f;
}
自由线;
直线=malloc(N);
}
r->字段=字段;
记录[SIZE++]=*r;
}
其他的
继续;
}
}
其他的
{
printf(“%s\n”,“无法打开文件”);
出口(1);
}
*长度=尺寸;
//fclose(fp);
退货记录;
}
int main()
{
整数长度=0;
struct record*records=get_记录(“./test.db”、&length);
//printf(“任何东西”);
int i=0;
对于(i=0;iName);
printf(“类型:%s\n”,r->Type);
}
返回0;
}
现在,我无法解决此实现中的两个问题:

  • main
    函数中有一个
    printf
    语句,如果未注释,循环中的
    printf
    将打印垃圾,否则将更正输出
  • 函数
    get_records
    中的
    fclose
    未注释会导致
    分段错误(堆芯转储)
    。通过反复试验,我发现我要么使用它,要么使用注释
    指定的
    malloc
    ,出于某种原因,使用其中一个或不使用它们,故障就会消失。我知道我在某个地方的内存分配有问题,我使用了
    valgrind
    ,但它没有帮助我找到任何东西
  • 注:

  • malloc
    中使用的常量用于测试目的。我们有包含100条记录的文件。这导致了未来的探索