0

I have this as my struct

    struct theFile{
        int count;
        FILE *fPointer;
        int *fileItems[];
    }myFile;

This is my method that saves the file in fileItems. It is saving the numbers properly. For example fileItems[0] = 5, fileItems[1] = 45, fileItems[2] = 35

    void saveFile(){
        myFile.fPointer = fopen("mileage.txt", "r");
        int i = 0;

        while (!feof(myFile.fPointer)){
            myFile.fileItems[i] = (int*)malloc(sizeof(int));
            fscanf(myFile.fPointer, " %d,", myFile.fileItems[i]);
            i++;
        }
        myFile.count = i;
    }

but when I go to print the contents of the file with this method it will print the first number properly but then it will print the rest as large numbers. Can someone please tell me why it isn't printing the correct content of the array.

    void viewFile(){
        for(int i = 0; i < myFile.count; i++){
            printf("%d, ", myFile.fileItems[i]);
        }
    }

also note, it is being written in c.

kRiZ
  • 2,320
  • 4
  • 28
  • 39
bobby
  • 5
  • 1
  • 1
    `fileItems` is an array of pointers, so you'll have to dereference it twice. At a guess: `&(myFile.fileItems[i])`. –  Dec 18 '14 at 09:45
  • 1
    But seen your usage of `fileItems`, you're better off declaring `fileItems` as an integer array: `int *fileItems`. Then change your `malloc` and `fscanf` accordingly. –  Dec 18 '14 at 09:47
  • 1
    any reason you din'r check for the success of `fopen()` or `malloc()`? BTW, please [do not cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()`. – Sourav Ghosh Dec 18 '14 at 09:49
  • `int *fileItems[];` is utterly wrong. What is your intention here? A potentially infinite array? Won't happen. `while(!feof` is wrong too, but straighten up your arrays first. – n. m. could be an AI Dec 18 '14 at 09:53
  • Evert- I didn't check because I'm just working through it right now. I had to cast malloc() otherwise I got an error. Invalid conversion form void to int* – bobby Dec 18 '14 at 10:00
  • n.m. - my intention was that it was going to have strings in it too, like a comma to separate the numbers then each number would be pointed to in the array. should I have it be just an array? – bobby Dec 18 '14 at 10:03
  • @bobby If `malloc` throws an error without a cast, you are likely using C++ compiler to compile C code. This is not recommended. See link posted by Sourav Ghosh for more details. – user694733 Dec 18 '14 at 10:11
  • What you have in `fileitems` is one question. How many of those things you have is another one. Having `int*`s where `int`s would suffice is suboptimal but not fatal, but you must decide on the "how many" question. No, `[]` doesn't mean "just enough". It is not legal C at all. – n. m. could be an AI Dec 19 '14 at 10:19

3 Answers3

2

int *fileItems[]; is equal to int ** fileItems; Most likely you want a array of integers, and not array of pointers to integers.

Change struct declaration to int * fileItems;, and allocate list once before loop:

myFile.fileItems = malloc(sizeof(int) * initialNumberOfElements);

Later, if initialNumberOfElements was too small, then in realloc more space:

myFile.fileItems = realloc(myFile.fileItems, sizeof(int) * biggerElementCount);

Then argument to fscanf must be &myFile.fileItems[i].

Don't forget add error handling code for cases when allocation function fails. Same goes for any file functions you use: all I/O can fail.

user694733
  • 15,208
  • 2
  • 42
  • 68
  • should the realloc be added in the while loop in the saveFile with an if statement that if(i>= initialNumberOfElements) then use realloc? – bobby Dec 18 '14 at 10:13
  • 1
    @bobby if it is possible, you should consider writing the number of `int` in the file before the `int` list, this way you can read the number, then allocate the correct number of `int`, and you won't have to `realloc`. – ElderBug Dec 18 '14 at 10:14
  • @bobby Yes thats, the idea. You probably want to keep the `currentArrayCapacity` variable around which tracks how big the array currently is. – user694733 Dec 18 '14 at 10:16
  • @ELderBug I never even thought of that. I think it's possible. Thanks! – bobby Dec 18 '14 at 10:20
1

fscanf ask for a pointer as argument, but it usually is the address of an existing int, not a 'real' int*. You probably meant to write :

struct theFile{
    int count;
    FILE *fPointer;
    int fileItems[N]; // You need to put a value as N, like 10, or else the array will be of size 0
}myFile;

Then

fscanf(myFile.fPointer, " %d,", &myFile.fileItems[i]); // with a & to get the address

This way you don't need a malloc and free. The rest is fine after that.

Edit: If you don't know how many int you will have beforehand, user694733's answer is better.

ElderBug
  • 5,926
  • 16
  • 25
  • This is reasonably simple alternative if `N` is known in advance. But loop should have additional `i < N` check just in case. Anyway, +1. – user694733 Dec 18 '14 at 10:07
0

Make your declaration in the structure.

struct theFile{
    int count;
    FILE *fPointer;
    int *fileItems[MAX];// MAX=10;
}myFile;

Empty array subscript cannot know how arrays to point.

Karthikeyan.R.S
  • 3,991
  • 1
  • 19
  • 31