csv

Unnamed repository
Log | Files | Refs

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:
Mcsv.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; }