我想解析形式为:grade(float), year(int), name(string), county(string), number(int)
的.csv
文件,我没有看到我的错误:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 300
typedef struct{
char *name, *county;
float grade;
unsigned long int year, number;
}info;
int main(int argc, char **argv)
{
FILE *fin = fopen("lab3.txt", "r");
if(!fin)
{
fprintf(stderr, "ERROR OPENING THE FILE.n");
exit(1);
}
char buf[MAX];
while(fgets(buf, MAX, fin))
{
buf[strcspn(buf,"n")] = ' '; // remove the trailing newline
char *fields[6], *word = strtok(buf, ",");
int i = 0;
while(word)
{
info *array = (info *)malloc(sizeof(info));
fields[i] = word;
array->name = strdup(fields[2]);
array->county = strdup(fields[3]);
array->grade = atof(fields[0]);
array->year = atoi(fields[1]);
array->number = atoi(fields[4]);
printf("Name : %s | County: %s | Year : %ld | Grade : %f | Number: %ld",array->name, array->county, array->year, array->grade, array->number);
//printf("Word : %sn", fields[i]);
word = strtok(NULL,",");
i++;
free(array->county);
free(array->name);
free(array);
}
}
fclose(fin);
return 0;
}
每行都有5个字段,所以我想把每行分解成单词,我也用gdb检查出了什么问题,问题似乎在这里array->name = strdup(fields[2]);
。到目前为止,我尝试了很多方法,我为数组分配了内存,我释放了内存,这是什么错误?
有很多问题。
你不需要[也不想要]fields
或word
。你可以使用realloc
来增加数组的大小,并直接对当前指针进行操作。
做malloc(sizeof(char))
,因为你有它,只是泄漏内存,因为strdup
在它之后。
你不不想在循环的底部执行free
——它只会杀死你执行strdup
的目的。
你不是在每次迭代中扩展array
的大小[使用realloc
],所以你的数组大小保持在1。而且,您在每次迭代时都会删除前一个值,因此,您再次泄漏内存。
这是一个重构的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 300
typedef struct {
char *name;
char *county;
float grade;
unsigned long int year;
unsigned long int number;
} info;
#define TOK
({
cp = strtok(bp,",");
bp = NULL;
cp;
})
#define SAVE_S(_sym)
arrcur->_sym = strdup(TOK)
#define SAVE_F(_sym)
arrcur->_sym = atof(TOK)
#define SAVE_I(_sym)
arrcur->_sym = atol(TOK)
int
main(int argc, char **argv)
{
FILE *fin = fopen("lab3.txt", "r");
if (!fin) {
fprintf(stderr, "ERROR OPENING THE FILE.n");
exit(1);
}
char buf[MAX];
info *arrbase = NULL;
int arrcnt = 0;
int arrmax = 0;
char *bp;
char *cp;
while (fgets(buf, MAX, fin)) {
// remove the trailing newline
buf[strcspn(buf, "n")] = ' ';
// enlarge array -- use of arrmax limits number of realloc calls
if (arrcnt >= arrmax) {
arrmax += 100;
arrbase = realloc(arrbase,sizeof(*arrbase) * arrmax);
}
// point to current array entry
info *arrcur = &arrbase[arrcnt];
bp = buf;
SAVE_S(name);
SAVE_S(county);
SAVE_F(grade);
SAVE_I(year);
SAVE_I(number);
printf("Name : %s | County: %s | Year : %ld | Grade : %f | Number: %ld",
arrcur->name, arrcur->county, arrcur->year, arrcur->grade,
arrcur->number);
++arrcnt;
}
fclose(fin);
// trim to size used
arrbase = realloc(arrbase,sizeof(*arrbase) * arrcnt);
return 0;
}