aocc23

Advent of Code 2023
git clone git://www.tkruger.se/aocc23.git
Log | Files | Refs | README

reading.c (2962B)


      1 #include "reading.h"
      2 
      3 size_t readall(char **output, char *filename) {
      4   FILE *f = NULL;
      5 
      6   f = fopen(filename, "r");
      7 
      8   if (f == NULL) {
      9     perror("Error when opening file");
     10     exit(EXIT_FAILURE);
     11   }
     12 
     13   char buffer[MAXIMUM_FILESIZE_BYTES];
     14   size_t read_size = fread(buffer, 1, MAXIMUM_FILESIZE_BYTES, f);
     15 
     16   if (read_size == MAXIMUM_FILESIZE_BYTES) {
     17     perror("File is to big?!");
     18     exit(EXIT_FAILURE);
     19   }
     20 
     21   *output = (char *)malloc(read_size + 1);
     22   memcpy(*output, buffer, read_size);
     23   (*output)[read_size] = '\0';
     24 
     25   return read_size;
     26 }
     27 
     28 size_t readlines(char ***lines, char *filename) {
     29   FILE *f = fopen(filename, "r");
     30 
     31   if (f == NULL) {
     32     perror("Error when opening file");
     33     exit(EXIT_FAILURE);
     34   }
     35 
     36   size_t tl_nalloc = LINES_ALLOC_MIN;
     37   size_t ntl = 0;
     38   char **tl = calloc(tl_nalloc, sizeof(*tl));
     39 
     40   char line_buffer[MAXIMUM_LINE_BYTES];
     41   while (fgets(line_buffer, MAXIMUM_LINE_BYTES, f)) {
     42     if (ntl == tl_nalloc) {
     43       tl_nalloc <<= 1;
     44       tl = realloc(tl, tl_nalloc * sizeof(*tl));
     45     }
     46 
     47     tl[ntl] = strdup(line_buffer);
     48 
     49     ntl++;
     50   }
     51 
     52   tl = realloc(tl, ntl * sizeof(*tl));
     53   *lines = tl;
     54 
     55   return (ntl);
     56 }
     57 
     58 int read_next_u64(uint64_t *n, FILE *fp) {
     59   int r, c = 0;
     60 
     61   // skip to next numerical char
     62   while ((r = fgetc(fp)) != EOF) {
     63     if ((int)'0' <= r && r <= (int)'9')
     64       break;
     65   }
     66   if (r == EOF)
     67     return EOF;
     68 
     69   // read an unsigned int
     70   *n = (uint64_t)(r - (int)'0');
     71   c++;
     72   while ((r = fgetc(fp)) != EOF) {
     73     if ((int)'0' <= r && r <= (int)'9') {
     74       *n = (*n) * 10UL + (uint64_t)(r - (int)'0');
     75       c++;
     76     } else {
     77       break;
     78     }
     79   }
     80 
     81   return c;
     82 }
     83 
     84 char *sread_next_u64(uint64_t *n, char *s) {
     85   char *fc = s;
     86 
     87   // skip to next numerical char
     88   while (*fc != '\0') {
     89     if ('0' <= *fc && *fc <= '9')
     90       break;
     91     fc++;
     92   }
     93   if (*fc == '\0')
     94     return NULL;
     95 
     96   // read an unsigned int
     97   *n = (uint64_t)(*fc - '0');
     98   fc++;
     99   while (*fc != EOF) {
    100     if ('0' <= *fc && *fc <= '9') {
    101       *n = (*n) * 10UL + (uint64_t)(*fc - '0');
    102     } else {
    103       break;
    104     }
    105     fc++;
    106   }
    107 
    108   if (*fc == '\0')
    109     return NULL;
    110 
    111   return fc;
    112 }
    113 
    114 char *sread_next_i64(int64_t *n, char *s) {
    115   char *fc = s;
    116 
    117   // skip to the next numerival char or -
    118   while (*fc != '\0') {
    119     if (('0' <= *fc && *fc <= '9') || *fc == '-')
    120       break;
    121     fc++;
    122   }
    123   if (*fc == '\0')
    124     return NULL;
    125 
    126   // -1 if starts with '-', otherwise +1
    127   int64_t sign = 1;
    128   if (*fc == '-') {
    129     sign = -1;
    130     fc++;
    131     // if no following digit this is interpreted as -0 == 0.
    132     if (*fc < '0' || *fc > '9') {
    133       *n = 0;
    134       if (*fc == '\0')
    135         return NULL;
    136       return fc;
    137     }
    138   }
    139 
    140   // read an unsigned int, starts with digit
    141   *n = (int64_t)(*fc - '0');
    142   fc++;
    143   while (*fc != EOF) {
    144     if ('0' <= *fc && *fc <= '9') {
    145       *n = (*n) * 10L + (int64_t)(*fc - '0');
    146     } else {
    147       break;
    148     }
    149     fc++;
    150   }
    151   // apply sign
    152   *n *= sign;
    153 
    154   if (*fc == '\0')
    155     return NULL;
    156 
    157   return fc;
    158 }