[ create a new paste ] login | about

Link: http://codepad.org/L43gXMZr    [ raw code | output | fork ]

C, pasted on Apr 19:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define xmalloc malloc
#define xfree free
#define xrealloc realloc

#define BUFFSIZE 3 /* >= 2 */
char *mygetline(FILE *fp) {
  static char inbuff[BUFFSIZE];
  char *outbuff_malloc, *tmpbuff;
  char *p, *r;
  int fEOL;

  if ((outbuff_malloc = xmalloc(1)) == NULL) {
    return NULL;
  }
  *outbuff_malloc = '\0';
  fEOL = 0;
  do {
    r = fgets(inbuff, BUFFSIZE, fp);
    if (r == NULL)
      break;
    for (p = inbuff; *p != '\0'; p++)
      ;
    if (*(p - 1) == '\n')
      fEOL = 1;
    if ((tmpbuff = xrealloc(outbuff_malloc, strlen(outbuff_malloc) + strlen(inbuff) + 1)) == NULL) {
      xfree(outbuff_malloc);
      return NULL;
    }
    strcat(tmpbuff, inbuff);
    outbuff_malloc = tmpbuff;
  } while (!fEOL);
  if (strlen(outbuff_malloc) > 0) {
    for (p = outbuff_malloc; *p != '\0'; p++)
      ;
    if (*(p - 1) == '\n')
      *(p - 1) = '\0';
    return outbuff_malloc;
  }
  xfree(outbuff_malloc);
  return NULL;
}

struct node {
  void *data;
  struct node *left;
  struct node *right;
};

void *push(struct node **root, void *data, int (*cmp)(void *, void *)) {
  struct node *p;
  int c;
  if (!*root) {
    p = xmalloc(sizeof(struct node));
    p->data = data;
    p->left = p->right = NULL;
    *root = p;
    return data;
  } 
  if ((c = (*cmp)(data, (*root)->data)) != 0) {
    if (c < 0) {
      return push(&((*root)->left), data, cmp);
    } else {
      return push(&((*root)->right), data, cmp);
    }
  }
  return (*root)->data;
}

void *pop(struct node **root) {
  struct node *p;
  void *data;
  if (*root == NULL) {
    return NULL;
  }
  if ((*root)->left) {
    data = pop(&((*root)->left));
    return data;
  }
  assert((*root)->left == NULL);
  p = *root;
  data = p->data;
  *root = p->right;
  xfree(p);
  return data;
}
/*------------------------------------------------------------*/
struct data1 {
  char *groupe;
  double j, m, e;
  int n;
};

int cmp_const1(char *a, char *b) {
  return 1;
}

void cut_tsv(char *line, struct node **root) {
  int s;
  char *p, *q, *col, c;
  p = q = line;
  do {
    c = *p;
    if (c == '\t' || c == '\0') {
      *p = '\0';
      s = strlen(q);
      if (s > 0) {
        col = xmalloc(s + 1);
        strcpy(col, q);
      } else
        col = NULL;
      push(root, col, (int (*)(void *, void *))cmp_const1);

      p++;
      q = p;
    } else {
      p++;
    }
  } while (c);
}

void usr_analyze_tsv(struct node **root, char **col1, char **col2, int *col3, int *col4, int *col5) {
  int i;
  char *p;
  for (i = 0; i < 5; i++) {
    if ((p = pop(root)) != NULL) {
      switch (i) {
      case 0:
        *col1 = p;
        break;
      case 1:
        *col2 = p;
        break;
      case 2:
        *col3 = atoi(p);
        xfree(p);
        break;
      case 3:
        *col4 = atoi(p);
        xfree(p);
        break;
      case 4:
        *col5 = atoi(p);
        xfree(p);
        break;
      }
    } else {
      switch (i) {
      case 0:
        *col1 = NULL;
        break;
      case 1:
        *col2 = NULL;
        break;
      case 2:
        *col3 = -1;
        break;
      case 3:
        *col4 = -1;
        break;
      case 4:
        *col5 = -1;
        break;
      }
    }
  }
}

void release_tsv(struct node **root) {
  char *p;
  while ((p = pop(root)) != NULL)
    xfree(p);
}

int cmp_data1(struct data1 *p, struct data1 *q) {
  if (!(p->groupe) || !(q->groupe))
    return 0;
  return strcmp(p->groupe, q->groupe);
}

void sum(struct node **root, char *line) {
  struct node *tsvroot;
  struct data1 *p, *q;
  int j, m, e;
  char *col1, *col2;

  tsvroot = NULL;
  cut_tsv(line, &tsvroot);
  usr_analyze_tsv(&tsvroot, &col1, &col2, &j, &m, &e);
  release_tsv(&tsvroot);
  xfree(col1);
  if (col2 == NULL || j < 0 || m < 0 || e < 0)
    return;
  p = xmalloc(sizeof(struct data1));
  if (!p) {
    fprintf(stderr, "cannot allocate enough memory.(analyze: struct data1)\n");
    exit(-1);
  }
  p->groupe = col2;
  p->n = 1;
  p->j = j;
  p->m = m;
  p->e = e;
  if ((q = push(root, p, (int (*)(void *, void *))cmp_data1)) != p) {
/*printf("analyze/push main/sol\n");*/
    xfree(col2);
    xfree(p);
    (q->n)++;
    (q->j) += j;
    (q->m) += m;
    (q->e) += e;
  } else {
/* printf("analyze/push main/dup\n");*/
  }    
}

void makeInfoCompare(double j, double m, double e, int infoCompare[]) {
  int i, k;
  double a, b;
  for (i = 0; i < 3; i++) {
    switch (i) {
    case 0:
      a = j;
      break;
    case 1:
      a = m;
      break;
    case 2:
      a = e;
      break;
    }
    for (k = 0; k < 3; k++) {
      switch (k) {
      case 0:
        b = j;
        break;
      case 1:
        b = m;
        break;
      case 2:
        b = e;
        break;
      }
      infoCompare[i * 3 + k] = (a > b) ? 1 : ((a < b) ? -1 : 0);
    }
  }
}

void listout(struct data1 *d, int infoCompareAve[], char *line) {
  struct node *tsvroot;
  char *col1, *col2;
  int j, m, e;
  int i, flag;
  int infoCompareStudent[3 * 3];

  tsvroot = NULL;
  cut_tsv(line, &tsvroot);
  usr_analyze_tsv(&tsvroot, &col1, &col2, &j, &m, &e);
  release_tsv(&tsvroot);
  if (col2 == NULL || j < 0 || m < 0 || e < 0)
    return;
  if (!strcmp(col2, d->groupe)) {
    makeInfoCompare((double)j, (double)m, (double)e, infoCompareStudent);
    flag = 1;
    for (i = 0; i < 3 * 3; i++) {
      if (infoCompareAve[i] == 0)
        continue;
      if (infoCompareStudent[i] != infoCompareAve[i]) {
        flag = 0;
        break;
      }
    }
    if (flag) {
      printf("name: %s : jpn:%d math:%d eng:%d\n", col1, j, m, e);
    }
  }
  xfree(col1);
  xfree(col2);
}

int main(int argc, char *argv[]) {
  FILE *fp;
  struct node *root;
  struct data1 *d;
  int infoCompare[3 * 3];
  char *p;
  if (argc != 2) {
    fprintf(stderr, "usage: %s <file>\n", argv[0]);
    return -1;
  }  
  if ((fp = fopen(argv[1], "r")) == NULL) {
    fprintf(stderr, "cannot opne the file '%s'\n", argv[1]);
    return -1;
  }
  root = NULL;
  while ((p = mygetline(fp))) {
    sum(&root, p);
    xfree(p);
  }
  while ((d = pop(&root))) {
    printf("groupe: %s\n", d->groupe);
    printf("jpn:%.1f, math:%.1f, eng:%.1f\n", d->j / d->n, d->m / d->n, d->e / d->n);
    makeInfoCompare(d->j, d->m, d->e, infoCompare);
    fseek(fp, 0, SEEK_SET);
    clearerr(fp);
    printf("---------------------\n");
    while ((p = mygetline(fp))) {
      listout(d, infoCompare, p);
      xfree(p);
    }
    putchar('\n');
    xfree(d->groupe);
    xfree(d);
  }
  fclose(fp);
/*  xmallocdump(); */
  return 0;
}
/* end */


Output:
1
2
3
usage: /t <file>

Exited: ExitFailure 255


Create a new paste based on this one


Comments: