csvinfo.c 1.9 KB

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