以下是需要解析的文件的一部分
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;
}
现在我对这个实现有两个问题,我无法弄清楚:
main
函数中有printf
语句,如果取消注释,循环内的printf
将打印垃圾,否则输出正确。fclose
中的get_records
会产生Segmentation fault (core dumped)
。通过反复试验,我发现我要么使用它,要么使用评论malloc
指定的HERE
行,出于某种原因使用其中一个或非故障消失。我知道我在某处使用内存分配有问题,我使用valgrind
但它没有帮助我找到任何东西注意:
malloc
中使用的常数用于测试目的。我们有包含100条记录的文件。这导致了一个未来的问题,更好地使用足够大的malloc
缓冲区或使用realloc
?C
中的任何其他实现(如果有):)答案 0 :(得分:0)
由于对malloc
和free
的多次调用,这个实现似乎大量搞砸了内存。我所做的是用数组替换结构中的char*
,将line
定义转换为char[]
,并在strtrim
调用中取消引用它。