#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSIZE 1024 /* >= 2 */
char *mygetline(FILE *fp) {
static char inbuff[BUFFSIZE];
char *outbuff_malloc, *tmpbuff;
char *p, *r;
int fEOL;
if ((outbuff_malloc = malloc(1)) == NULL) {
return NULL;
}
*outbuff_malloc = '\0';
fEOL = 0;
do {
r = fgets(inbuff, BUFFSIZE, fp);
if (r == NULL)
break;
for (p = inbuff; *p != '\0'; p++)
;
if (*(p - 1) == '\n')
fEOL = 1;
if ((tmpbuff = realloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) == NULL) {
free(outbuff_malloc);
return NULL;
}
strcat(tmpbuff, inbuff);
outbuff_malloc = tmpbuff;
} while (!fEOL);
if (strlen(outbuff_malloc) > 0) {
for (p = outbuff_malloc; *p != '\0'; p++)
;
if (*(p - 1) == '\n' || *(p - 1) == '\r')
*(p - 1) = '\0';
/* fixed */
if (*(p - 2) == '\n' || *(p - 2) == '\r')
*(p - 2) = '\0';
return outbuff_malloc;
}
free(outbuff_malloc);
return NULL;
}
void ReadN(FILE *fp, int *n) {
char *p;
if ((p = mygetline(fp)) != 0) {
sscanf(p, "%d", n);
free(p);
}
}
char *cutToken(char *p, char **s) {
char *t, *q;
int flag;
if (p == 0)
return 0;
flag = 0;
for (q = p; *q == ' ' && *q != '\0'; q++)
;
if (*q == '\0')
return 0;
t = q;
q++;
for (; *q != ' ' && *q != '\0'; q++)
;
if (*q == '\0')
flag = 1;
*q = '\0';
if (flag)
*s = 0;
else
*s = q + 1;
return t;
}
void ReadTitle(FILE *fp, int m, int n, char **kamokus) {
char *p, *q, *t;
int i;
for (i = 0; i < m; i++)
kamokus[i][0] = '\0';
if ((p = mygetline(fp)) != 0) {
q = p;
for (i = 0; i < m; i++) {
if((t = cutToken(q, &q)) == 0)
return;
strncpy(kamokus[i], t, n - 1);
kamokus[i][n - 1] = '\0';
if (!q)
break;
}
free(p);
}
}
void ReadBody(FILE *fp, char **names, int **tensu, int n, int m) {
char *buff, *p, *t;
int i;
if ((buff = mygetline(fp)) != 0) {
names[n] = buff;
p = buff;
cutToken(p, &p);
for (i = 0; i < m; i++)
if ((t = cutToken(p, &p)) != 0)
tensu[n][i] = atoi(t);
/* free(buff); */
}
}
void vomitBody(int n, int m, char *names[], int **tensu) {
int i, j;
for (i = 0; i < n; i++) {
printf("%s : ", names[i]);
for (j = 0; j < m; j++)
printf("%d ", tensu[i][j]);
putchar('\n');
}
}
void aveStu(int n, int m, char *names[], int **tensu) {
int i, j;
double s;
for (i = 0; i < n; i++) {
printf("%s : ", names[i]);
s = 0.0;
for (j = 0; j < m; j++)
s += tensu[i][j];
printf("%.1f\n", s / m);
}
}
void aveKamoku(int n, int m, char *kamokus[], int **tensu) {
int i, j;
double s;
for (i = 0; i < m; i++) {
printf("%d %s : ", i, kamokus[i]);
s = 0.0;
for (j = 0; j < n; j++)
s += tensu[j][i];
printf("%.1f\n", s / n);
}
}
int main(int argc, char *argv[]) {
int **tensu;
char **names;
int n, i;
FILE *fp;
#define K 6
static char kamoku1[K], kamoku2[K], kamoku3[K], kamoku4[K];
#define M 4
static char *kamokus[M] = { kamoku1, kamoku2, kamoku3, kamoku4 };
if (argc != 2) {
fprintf(stderr, "usage: %s <data-file>\n", argv[0]);
exit(1);
}
if ((fp = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "cannot open the file '%s'\n", argv[1]);
exit(1);
}
ReadN(fp, &n);
printf("n = %d\n", n);
ReadTitle(fp, M, K, kamokus);
if ((tensu = malloc(sizeof(int *) * n)) != 0) {
for (i = 0; i < n; i++)
tensu[i] = malloc(sizeof(int) * M);
if ((names = malloc(sizeof(char *) * n)) != 0) {
/* 1 */
for (i = 0; i < n; i++)
ReadBody(fp, names, tensu, i, M);
/* 2 */
vomitBody(n, M, names, tensu);
putchar('\n');
/* 3 */
aveStu(n, M, names, tensu);
putchar('\n');
/* 4 */
aveKamoku(n, M, kamokus, tensu);
for (i = 0; i < n; i++)
free(names[i]);
free(names);
}
for (i = 0; i < n; i++)
free(tensu[i]);
free(tensu);
}
fclose(fp);
return 0;
}
/* end */