2013-04-03 149 views
1

因此,任务是读取文件并将数据推送到结构。数据文件:C结构,内存分配和结构

babe 12 red 12 
deas 12 blue 12 
dsa 12 red 512 
bxvx 15 blue 52 
reed 18 black 15 

而代码是类似的东西

struct shoes { 
    char name[8]; 
    int size; 
    char color[8]; 
    int price;  
}; 
//open file 
shoes *item=(struct shoes*)malloc(sizeof(struct shoes)); 
for (i=0; !feof(file); i++) { 
    item=(struct shoes*)realloc(item,sizeof(struct shoes)+i*sizeof(struct shoes)); 
    fscanf(file,"%s %i %s %i\n",(item+i)->name,(item+i)->size,(item+i)->color,(item+i)->price); 
} 

但该程序崩溃每次。 012gdbg说:当前上下文中没有符号“item”。 哪里出错?

回答

3

你的代码有一些错误: 1)您需要的鞋子,除非你用C++编译器编译的typedef ......但你应该标记这个C++。 2)feof不会返回false,直到尝试超出文件末尾的读取结果,所以您的代码会让鞋子数组太大。 3)你将整数传递给fscanf而不是他们的地址。

如果编译为C代码,而不是C++代码,则malloc和realloc上的强制转换不是必需的,因此建议不要。还有其他的风格问题让你的代码难以理解。试试这个:

typedef struct { 
    char name[8]; 
    int size; 
    char color[8]; 
    int price;  
} Shoe; 

// [open file] 

Shoe* shoes = NULL; // list of Shoes 
Shoe shoe; // temp for reading 

for (i = 0; fscanf(file,"%s %i %s %i\n", shoe.name, &shoe.size, shoe.color, &shoe.price) == 4; i++) 
{ 
    shoes = realloc(shoes, (i+1) * sizeof *shoes); 
    if (!shoes) ReportOutOfMemoryAndDie(); 
    shoes[i] = shoe; 
} 
+0

是的,我用过gcc,所以它工作正常。我会更好地遵循未来的规范) – ovnia

+0

@wingsofovnia我有一个重要的错字,我已经修好了......'鞋子'=鞋子',而不是'鞋子'。 –

+0

为什么要读入临时文件,而不是直接到位? –

2

你确定调试器这么说吗?我很惊讶它甚至编译...

你想:

struct shoes *item 

如果你没有证明你的结构的一个typedef,你必须明确地说“结构”每次引用它的时间。

秒注意:

item=(struct shoes*)realloc(item... 

不相同的指针从你进入它realloc()分配。如果重新分配失败,它将返回NULL,这可能会杀死你。你应该确保你正在检查的初始malloc()两者的结果和realloc()

第三点:

您必须经过地址廉政局的到fscanf()函数。

fscanf(file,"%s %i %s %i\n",(item+i)->name,&((item+i)->size),(item+i)->color,&((item+i)->price)); 
+0

反正崩溃仍然在这里( – ovnia

+0

@wingsofovnia - OK,首先要检查我的更新,请检查您的回报,看看是否分配总是成功的二什么是*确切*错误,你得到的。 ,并发生什么行? – Mike

+0

崩溃发生在fscanf行 – ovnia

3

的问题是,你是不是传递指针您要使用fscanf阅读整数,要传递的整数自己。

fscanf将它们视为指针。他们在哪里指出?谁知道 - 整数未初始化,所以他们可以指向任何地方。因此,CRASH

修复正是如此:

fscanf(file,"%s %i %s %i\n", 
    (item+i)->name, 
    &((item+i)->size), 
    (item+i)->color, 
    &((item+i)->price)); 

请注意,您因为数组退化为指针,不需要同为namecolor,所以你传递了正确的事情了。

请考虑开水item+i表示法; item[i]这么更清晰,更易于理解的时候随便读取的代码为:

fscanf("%s %i %s %i\n", 
    item[i].name, 
    &item[i].size, 
    item[i].color, 
    &item[i].price); 
+0

谢谢,一切似乎都很好。但有一些问题:1)为什么(item + i) - >大小不是指针? while(item + i) - > name是一个指针? 2)是ptr +我等于ptr [i],对吗? – ovnia

+1

我向你解释了原因:'name'是一个数组,数组将退化为指针;所以当你尝试传递'(item + i) - > name'时,你传递了一个指向数组的第一个元素的指针。另一方面'大小'不是一个数组,它是一个整数。你需要明确地获得一个*指针*给它赋予'fscanf',这就是为什么'&'(“address-of”运算符)是必需的。是的,'ptr + i'和'ptr [i]'是一样的,但是下标语法有点清晰,并且避免了括号的需要。 –

+0

谢谢你帮助noob)我知道了) – ovnia

1

有两个问题与您的代码:

1日。该结构:

,你可以有两种方式, 你的方式定义你的结构:

struct shoe{  
char name[8]; 
int size; 
char color[8]; 
int price; 
}; 

在这种情况下,你应该是指它的指针为:

struct shoe *item; 

另一种(也许更方便?)的方式使用typedef与defenition:

typedef struct {  
char name[8]; 
int size; 
char color[8]; 
int price; 
} shoe; 

在这种情况下,你应该是指它的指针为:

shoe *item; 

因此,您发布的代码不应该编译。

第二届一个:

的fscanf应给予指向整数/的情况下字符你教。 你已经正确地传递了char指针(因为你传递了一个char数组的名字,它实际上是一个指向第一个元素的char指针),但是你已经传递了一些整数并且fscanf需要指向它应该填充的整数的指针,所以你的代码应该是:

fscanf(file,"%s %i %s %i\n",(item+i)->name,&((item+i)->size),(item+i)->color,&((item+i)->price));