LINUX.ORG.RU

История изменений

Исправление firkax, (текущая версия) :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#define MAX_STATIONS 1000
#define MAX_NAMESIZE 32
#define HSIZE 5381

typedef struct {
  unsigned int hash;
  unsigned int next;
  int       min;
  int       max;
  long long sum;
  long long count;
  char      name[MAX_NAMESIZE];
} station;

static station sts[MAX_STATIONS];
static unsigned int hst[HSIZE];
static unsigned int nst;



static char b[1048576];
static size_t bs, bp;
static unsigned long lines;

static int stcmp(void const *a, void const *b) { return strcmp(((station*)a)->name, ((station*)b)->name); }

int main(void) {
  ssize_t r;
  size_t p;
  unsigned int hash;
  char c;
  station *st;
  unsigned int sti;
  int neg;
  unsigned int val, vv, h;
  
  while(1) {
    r = read(0, b+bs, sizeof(b)-bs);
    if(r<0) { fprintf(stderr, "warning: read error %d (%s)\n", errno, strerror(errno)); break; }
    if(!r) break;
    bs += r;
    for(h=5381,p=bp; p<bs; p++) {
      if((c=b[p])==';') {
        for(sti=hst[h%HSIZE]; ; sti=st->next) {
          if(!sti) {
            if(nst==MAX_STATIONS) { fprintf(stderr, "too many stations"); return -1; }
            st = sts+(sti=nst++);
            st->hash = h;
            bcopy(b+bp, st->name, p-bp);
            st->name[p-bp] = 0;
            st->next = hst[h%HSIZE];
            hst[h%HSIZE] = sti+1;
            break;
          }
          if((st=sts+(sti-1))->hash==h && !strncmp(st->name,b+bp,p-bp) && !st->name[p-bp]) break;
        }
        p++;
        if(bs-p<2) break;
        if(b[p]!='-') neg=1; else { neg=-1; p++; }
        val = 0;
        while(1) {
          if(p>=bs || (c=b[p])<'0' || c>'9') break;
          vv = val*10+(c-'0');
          if(vv/10!=val) { fprintf(stderr, "bad input data\n"); return -1; }
          val = vv; p++;
        }
        if(p>=bs) break;
        if(b[p]=='.') {
          p++;
          if(bs-p<2 || (c=b[p])<'0' || c>'9') break;
          vv = val*10+(c-'0');
          if(vv/10!=val) { fprintf(stderr, "bad input data\n"); return -1; }
          val = vv; p++;
        } else {
          vv = val*10;
          if(vv/10!=val) { fprintf(stderr, "bad input data\n"); return -1; }
          val = vv;
        }
        if(p>=bs) break;
        if(b[p]!='\n' || (int)val<0) { fprintf(stderr, "bad input data\n"); return -1; }
        neg*=val;
        if(!st->count || neg<st->min) st->min = neg;
        if(!st->count || neg>st->max) st->max = neg;
        st->sum += neg;
        st->count++;
        bp = p+1; h=5381;
        lines++;
        continue;
      }
      h += h<<5;
      h ^= (unsigned char)(b[p]);
    }
    if(!bp) { fprintf(stderr, "bad input data\n"); return -1; }
    if(bs -= bp) bcopy(b+bp, b, bs);
    bp = 0;
  }
  if(lines!=1000000000) fprintf(stderr, "warning: got %lu lines, not 1000000000\n", lines);
  qsort(sts, nst, sizeof(*sts), stcmp);
  for(val=0,st=sts; val<nst; val++,st++) {
    neg = st->sum/st->count;
    printf("%s%s=%d.%u/%d.%u/%d.%u", val?", ":"{", st->name, st->min/10, abs(st->min)%10, neg/10, abs(neg)%10, st->max/10, abs(st->max)%10);
  }
  printf(nst?"}\n":"{}\n");
  return 0;
}

вроде компилируется и на файле из 7 строк работает, дальше не проверял

Исходная версия firkax, :