Reputation: 37
The code down below is suppose to read and store an input-ed text file and store its contents in the structure appropriately, dynamically. The first number is number of albums, second is number of tracks within this album, and the number in front of each title is the number of characters in that title.
For the code I have written so far, I am trying to make it so that each album correlates to 1 independent structure each, so I created a Struct array. So currently right now I am able to read in the number of albums and number of tracks correctly. However, I am having trouble with the pointer array in struct album
. I am having trouble both dynamically allocating the correct memory for it, as well as storing all (in this case 17) track names into the entire pointer array, without the numbers in front of the track titles.
Example Text File:
1
17
16 Like an umbrella
...
15 Dynasty Warrior
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct album
{
int num_tracks;
char *tracks[];
};
int main(int argc, char *argv[]){
int numbALBUMS=0, numbCharInTrack=0;
int i=0,j=0;
FILE *albums;
albums = fopen (argv[1], "r");
fscanf(albums, "%d", &numbALBUMS);
struct album info[numbALBUMS];
for(i=0;i<numbALBUMS;i++){
fscanf(albums, "%d", &info[i].num_tracks);
for(j=0;j<info[i].num_tracks;j++){
fscanf(albums, "%d" , &numbCharInTrack);
//NEED HELP HERE
//fscanf(albums,"s",info[i].tracks[j]);
}
}
fclose(albums);
return 0;
}
Upvotes: 1
Views: 173
Reputation: 646
struct Album info[numAlbums]
is incorrect, you have to do something like this :
struct Album *info = (struct album*)malloc(numAlbums * sizeof(struct Album));
A statement of the form type name[numOfElements];
can only be used for static allocation.
You should replace char *tracks[]
with char **tracks
. You can use char *tracks[], but this is more difficult.(if you want to have a look a it : What's the need of array with zero elements?)
You then have to add
info[i].tracks = malloc(sizeof(char*) * info[i].num_tracks);
in the first for loop after the fscanf
statement.
To end, you have to allocate in the innermost for loop, after the first fscanf
statement, memory for the string that holds the trak name. You can do that like this :
info[i].tracks[j] = malloc(sizeof(char) * (numbCharInTrack + 1)); //number of characters + '\0'
Then you can read the track name from the file.
fgetc(album); //Read past the leading space
fgets(info[i].tracks[j], numbCharInTrack + 1, album);
Edit
Added read name from file code.
Replaced malloc(sizeof(char) * numbCharInTrack)
with malloc(sizeof(char) * (numbCharInTrack + 1))
, forgot terminating null character.
Upvotes: 2