This is an example of what I was thinking of - but it's not as good as I'd like it to be. Seems a bit inelegant.
This version only does one group, would need a while (there is more input) loop around it, to handle more blocks.
What I really wouldn't like is the constant realloc() for more memory, with every block of data. Make the initial size something big enough to handle 300 structs or so, and realloc() another 200 or 300, if needed.
That's why I made the ratings array, just big.
To make this simple, I have another idea. Read each row of the file with fgets(), and if buff[0] < 'A', then it's a number. put all the numbers in one file, (in order), and all the names into another file (also in their original order). Then malloc all your arrays from reading the file. Ignore or throw out the group and each numbers.
That avoids several complications in the code, including the structs. If you need to sort the names, or etc., then use an index or pointer array to make it appear sorted, and leave the data in it's original order.
Code:
/*
Contents of 0dan.txt
2
3
Adam Bob Carl
Diana Ellen Fran
4 8 7
6 7 5
5 9 6
7 6 8
6 5 9
4 7 3
2
Brad Tom
Katie Angelina
5 8
9 7
4 8
7 6
first number is num groups. 2nd number in num each. then the names. then adams ratings, bobs, carls, diana, ellen, fran, then next group.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NLen 19
#define ROW 50
#define COL 50
typedef struct {
char name[NLen];
char sex;
int id;
}rec;
int main(void) {
char buff[128], ch;
char *pbuff;
int i, j, count, groups, each, num;
int ratings[ROW][COL]={0};
FILE *fp;
rec *names;
if((fp=fopen("0dan.txt", "rt")) == NULL) {
printf("\nError opening data file - terminating");
return 1;
}
fgets(buff, sizeof(buff), fp);
groups = buff[0]-'0';
fgets(buff, sizeof(buff), fp);
each = buff[0]-'0';
printf("\n\ngroups: %d each: %d", groups, each);
num=groups*each;
names = malloc(num * sizeof(rec));
if(names==NULL) {
printf("\nError allocating memory");
return 1;
}
for(i=0, count=0;i<groups;i++) {
buff[0]='\0';
pbuff = buff;
fgets(buff, sizeof(buff), fp);
for(j=0;j<each;j++) {
sscanf(pbuff, "%s", names[count].name);
if(i%2==0)
names[count].sex = 'M';
else
names[count].sex = 'F';
names[count].id = count+1;
pbuff += strlen(names[count++].name)+1;
}
}
//for(i=0;i<count;i++)
//printf("\n%-19s %c %2d", names[i].name, names[i].sex, names[i].id);
/* get the ratings */
for(i=0;i<count;i++) {
for(j=0;j<each;j++) {
fscanf(fp, "%d", &ratings[i][j]);
fscanf(fp, "%c", &ch);
}
}
printf("\n\nName Sex ID Ratings\n");
printf("====================================");
for(i=0;i<count;i++) {
printf("\n%-19s %c %2d ", names[i].name, names[i].sex, names[i].id);
for(j=0;ratings[i][j]>0;j++) {
printf(" %d", ratings[i][j]);
}
}
fclose(fp);
free(names);
printf("\n\n\t\t\t press enter when ready");
i=getchar();
return 0;
}
//Output:
groups: 2 each: 3
Name Sex ID Ratings
====================================
Adam M 1 4 8 7
Bob M 2 6 7 5
Carl M 3 5 9 6
Diana F 4 7 6 8
Ellen F 5 6 5 9
Fran F 6 4 7 3
press enter when ready