commit eb5cc48c716d078349eda821bab263af80757fe3
parent d666838b2ad0776a1e2bb9fef8e2e8ef6de60278
Author: aabacchus <ben@bvnf.space>
Date: Sat, 2 Oct 2021 16:14:32 +0100
move data reading into its own function
Diffstat:
M | csv.c | | | 130 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 77 insertions(+), 53 deletions(-)
diff --git a/csv.c b/csv.c
@@ -34,6 +34,74 @@ read_header(FILE *f, char ***header) {
return ncols;
}
+/* read_data reads all the comma-separated values from f into *datap,
+ * and returns the number of rows.
+ * This function mallocs the number of rows in *header[0..n-1]
+ * -1 is returned on error.
+ */
+int
+read_data(FILE *f, float ***datap, int ncols) {
+ float **data = *datap;
+ int nrows = 0;
+ char *n = malloc(MAX_LINE);
+ if (n == NULL) {
+ perror("malloc");
+ return -1;
+ }
+ char *np = n;
+ data[0] = malloc(sizeof (float) * ncols);
+ if (data[0] == NULL) {
+ perror("malloc");
+ free(n);
+ return -1;
+ }
+ int c, x, y;
+ x = y = 0;
+ while ((c = fgetc(f)) != EOF) {
+ if (c == ',' || c == '\n') {
+ if (n == np) {
+ /* nothing in this column */
+ fprintf(stderr, "warning: empty cell at row %d, col %d\n", y + 1, x + 1);
+ data[y][x] = 0.;
+ } else {
+ *np++ = '\0';
+ data[y][x] = (float)atof(n);
+ np = n;
+ }
+ x++;
+ if (c == '\n') {
+ nrows++;
+ y++;
+ x = 0;
+ float **tmp = realloc(data, sizeof (float *) * (nrows + 1));
+ if (tmp == NULL) {
+ perror("malloc");
+ goto cleanup;
+ }
+ data = tmp;
+ data[y] = malloc(sizeof (float) * ncols);
+ if (data[y] == NULL) {
+ nrows--;
+ perror("malloc");
+ goto cleanup;
+ }
+ continue;
+ }
+ continue;
+ }
+ *np++ = c;
+ }
+ free(n);
+ *datap = data;
+ return nrows;
+cleanup:
+ free(n);
+ for (int i = 0; i < nrows; y++)
+ free(data[i]);
+ free(data);
+ return -1;
+}
+
int
main(int argc, char **argv) {
int c;
@@ -89,54 +157,16 @@ read from stdin\n"
}
/* read data */
- char *n = malloc(MAX_LINE);
- char *np = n;
- int nrows = 0;
- float **data;
- data = malloc(sizeof (float *) * (nrows + 1));
+ float **data = malloc(sizeof (float *) * 1);
if (data == NULL) {
perror("malloc");
- goto fail;
- }
- data[0] = malloc(sizeof (float) * ncols);
- if (data[0] == NULL) {
- perror("malloc");
- goto fail;
+ return 1;
}
- np = n;
- int x, y;
- x = y = 0;
- while ((c = fgetc(f)) != EOF) {
- if (c == ',' || c == '\n') {
- if (n == np) {
- /* nothing in this column */
- fprintf(stderr, "warning: empty cell at row %d, col %d\n", y + 1, x + 1);
- data[y][x] = 0.;
- } else {
- *np++ = '\0';
- data[y][x] = (float)atof(n);
- np = n;
- }
- x++;
- if (c == '\n') {
- nrows++;
- y++;
- x = 0;
- data = realloc(data, sizeof (float *) * (nrows + 1));
- if (data == NULL) {
- perror("malloc");
- goto fail;
- }
- data[y] = malloc(sizeof (float) * ncols);
- if (data[y] == NULL) {
- perror("malloc");
- goto fail;
- }
- continue;
- }
- continue;
- }
- *np++ = c;
+ int nrows = read_data(f, &data, ncols);
+ if (nrows == -1) {
+ free(data);
+ fclose(f);
+ return 1;
}
for (int i = 0; i < nrows; i++) {
for (int j = 0; j < ncols; j++)
@@ -145,15 +175,9 @@ read from stdin\n"
}
fprintf(stderr, "table has %d rows of %d columns\n", nrows, ncols);
- free(n);
+ for (int i = 0; i < nrows; i++)
+ free(data[i]);
free(data);
-
-
fclose(f);
return 0;
-fail:
- fclose(f);
- free(n);
- free(data);
- return 1;
}