1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
/*
csvinfo - reads CSV data from input file(s) and reports the number
of fields and rows encountered in each file
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <csv.h>
struct counts {
long unsigned fields;
long unsigned rows;
};
void cb1 (void *s, size_t len, void *data) { ((struct counts *)data)->fields++; }
void cb2 (int c, void *data) { ((struct counts *)data)->rows++; }
static int is_space(unsigned char c) {
if (c == CSV_SPACE || c == CSV_TAB) return 1;
return 0;
}
static int is_term(unsigned char c) {
if (c == CSV_CR || c == CSV_LF) return 1;
return 0;
}
int
main (int argc, char *argv[])
{
FILE *fp;
struct csv_parser p;
char buf[1024];
size_t bytes_read;
unsigned char options = 0;
struct counts c = {0, 0};
if (argc < 2) {
fprintf(stderr, "Usage: csvinfo [-s] files\n");
exit(EXIT_FAILURE);
}
if (csv_init(&p, options) != 0) {
fprintf(stderr, "Failed to initialize csv parser\n");
exit(EXIT_FAILURE);
}
csv_set_space_func(&p, is_space);
csv_set_term_func(&p, is_term);
while (*(++argv)) {
if (strcmp(*argv, "-s") == 0) {
options = CSV_STRICT;
csv_set_opts(&p, options);
continue;
}
fp = fopen(*argv, "rb");
if (!fp) {
fprintf(stderr, "Failed to open %s: %s\n", *argv, strerror(errno));
continue;
}
while ((bytes_read=fread(buf, 1, 1024, fp)) > 0) {
if (csv_parse(&p, buf, bytes_read, cb1, cb2, &c) != bytes_read) {
fprintf(stderr, "Error while parsing file: %s\n", csv_strerror(csv_error(&p)));
}
}
csv_fini(&p, cb1, cb2, &c);
if (ferror(fp)) {
fprintf(stderr, "Error while reading file %s\n", *argv);
fclose(fp);
continue;
}
fclose(fp);
printf("%s: %lu fields, %lu rows\n", *argv, c.fields, c.rows);
}
csv_free(&p);
exit(EXIT_SUCCESS);
}
|