Question: I'm new to C, and for my class, we have a project where we have to write a function that reads all the items in the file and returns them in file-order, in a dynamically created list.
Each line of the file is one item and has the format:

```
'<description>' <damage> <cost> <weight>

```

It's supposed to return a base pointer to items in file in file order, or NULL if file doesn't exist.

Here's my code so far:

```
item_t *ReadItemsFromFile(char *file)
{
typedef struct item item_t;
struct item
{
   char name[32];
   float cost, weight;
   int dam;
};FILE *fpin = fopen(file, "r");

if(fpin != NULL)
{
  item_t i[20];
  int n = 0;
  char line[sizeof(file)];
  while(fgets(line, sizeof(line), fpin) != NULL){
      (fscanf(fpin, " '%[^']' %d %f %f", i[n].name, &i[n].dam, &i[n].cost, &i[n].weight));
  fputs(i[n].name, stdout);
  n++;
}
} else {
  return NULL;
} 
  return(0);
}

```

I've been using fputs to try to test the code, but it keeps giving me gibberish for the first and last items.
Also, when I try putting

```
fputs(&i[n].dam, stdout);

```

so I can test the other variables for the struct, I keep getting an error saying "passing argument 1 of 'fputs' from incompatible pointer type.

I'm not sure if I'm accurately passing into struct variables using fscanf, or if it's something else.

Answer: 
One problem is that you use `fgets` to read a line from the file into `line`, but you then ignore that line and use `fscanf` to read from the next line. You should use `sscanf` to parse the line you just read instead. Alternately, don't use `fgets` at all and just `fscanf` directly it the while condition:

```
while(4 == fscanf(fpin, " '%[^']'%d%f%f", i[n].name, &i[n].dam, &i[n].cost, &i[n].weight)) {
    fputs(i[n].name, stdout);
    n++; }

```

Another problem is that you declare `line` just large enough to hold `sizeof(char *)` characters -- probably just 4 or 8, which won't be big enough for an entire line, so you'll only be able to read part of the line. You need to declare it big enough to hold the longest line in the file.

A third problem is that you declare `struct item` and `item_t` as local to the function, which means that your code won't even compile as you try to use `item_t` outside the function as part of its return type. You need to move the delcarations to the global scope before the function declaration.

A fourth problem is that you declare the item array that you're reading into (`i`) as a local variable, so you won't be able to return it from the function -- if you do, the pointer you return will point at garbage. But since you always return NULL, you won't see that problem.
Okay, I stopped using fgets() and moved the struct outside of the function, but I'm still having issues returning the pointer. I keep trying to return the pointer after mallocing it, but it informs me of "return from incompatible pointer type". Here's my code so far:

```
struct items_t
{
   char name[32];
   float cost, weight;
   int dam;
};
typedef struct items_t items_t;

item_t *ReadItemsFromFile(char *file)
{

  FILE *fpin = fopen(file, "r");

if(fpin)
{   
  items_t i[50];
  int n = 0;

   while(4 == (fscanf(fpin, " '%[^']' %d %f %f", i[n].name, &i[n].dam, &i[n].cost, &i[n].weight)))
{
  n++;
  items_t *a = (items_t*)malloc(sizeof(items_t));
  return(&a);

}
} else {
  return NULL; 
}
return(0);

}

```