Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Critique my C code

Name: Anonymous 2013-03-29 1:08

Took me about 2 hours to write this. There are some areas I know of to improve I just wanted to get it done. I'm just asking because I want to know if I should continue programming or if I should start scrubbing toilets with Kodak-kun.

The program parses through data files and gives the mins and maxes for each field. It also auto detects the header and ignors it. It displays the mins and maxes of each field as well as the line number. In addition it will accept a directory instead of a single file and iterate through all files with a user defined extension.


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>

#define SINGLE_FILE 0
#define DIRECTORY 1

#define MAX_PATH 250
#define MAX_EXT 10
#define MAX_BUFF 250
#define DATA_MAX 50

void find_maxes(char *path);
void find_fields(char *path, int *fields, int *start_line);
int get_fields(char *s);
void split_data(double *data, char *s,  int fields);

int main(int argc, char **argv) {
  int type, file_count;
  char path[MAX_PATH], ext[MAX_EXT];
 
  if(argc > 2 && !strcmp(argv[1], "-s")) {
    type = SINGLE_FILE;
    if(strlen(argv[2]) > MAX_PATH) {
      fputs("Path length too long\n", stdout);
      exit(1);
    }
    strcpy(path, argv[2]);
  }
  else if(argc > 3 && !strcmp(argv[1], "-d")) {
    type = DIRECTORY;
    if(strlen(argv[2]) > MAX_PATH || strlen(argv[3]) > MAX_EXT) {
      fputs("Path or extension length too long\n", stdout);
      exit(1);
    }
    strcpy(path, argv[2]);
    strcpy(ext, argv[3]);
  }
  else {
    fprintf(stdout, "Usage: '%s -s file_path'\n"
    "or\n"
    "'%s -d directory_path extension'\n", *argv, *argv);
    exit(2);
  }
 
  if(type == SINGLE_FILE) {
    find_maxes(path);
  }
  else {
    struct dirent *dp;
    DIR *dfd = opendir(path);
    char fn[MAX_PATH], full_path[MAX_PATH];
    if(!dfd) {
      fprintf(stdout, "Can't open directory '%s'\n", path);
      exit(3);
    }
   
    while(dp = readdir(dfd)) {
      strcpy(fn, dp->d_name);
      if(!strncmp(fn+strlen(fn)-strlen(ext), ext, strlen(ext))) {
        fprintf(stdout, "In %s\n", fn);
        sprintf(full_path, "%s%s", path, fn);
        find_maxes(fn);
      }
    }
  }
  return(EXIT_SUCCESS);
}

void find_maxes(char *path) {
  int fields, start_line, line_no = 0, i;
  char buff[MAX_BUFF];
 
  find_fields(path, &fields, &start_line);
 
  FILE *f = fopen(path, "r");
 
  if(!f) {
    fprintf(stdout, "Error opening %s\n", path);
    perror("fopen");
  }
 
  double *data, *maxes, *mins;
  int *line_min, *line_max;
 
  data = (double *) malloc(sizeof(double) * fields);
  maxes = (double *) malloc(sizeof(double) * fields);
  mins = (double *) malloc(sizeof(double) * fields);
  line_min = (int *) malloc(sizeof(int) * fields);
  line_max = (int *) malloc(sizeof(int) * fields);
 
  for(i = 0; i < fields; i++) {
    maxes[i] = -1e100;
    mins[i] = +1e100;
    line_min[i] = 0;
    line_max[i] = 0;
  }
 
  while(fgets(buff, MAX_BUFF, f) && ++line_no < start_line)
    ;
   
  while(fgets(buff, MAX_BUFF, f)) {
    line_no++;
    if(get_fields(buff) != fields)
      continue;
    else
      split_data(data, buff, fields);
   
    for(i = 0; i < fields; i++) {
      if(data[i] > maxes[i]) {
        maxes[i] = data[i];
        line_max[i] = line_no;
      }
      if(data[i] < mins[i]) {
        mins[i] = data[i];
        line_min[i] = line_no;
      }
    }
  }
 
 
  for(i = 0; i < fields; i++)
    printf("Field %d: Max = %lf @ line %d\tMin = %lf @ line %d\n", i, maxes[i], line_max[i], mins[i], line_min[i]);
 
  free(data);
  free(maxes);
  free(mins);
  free(line_min);
  free(line_max);
  fclose(f);
}

void find_fields(char *path, int *fields, int *start_line) {
  FILE *f = fopen(path, "r");
  if(!f) {
    fprintf(stdout, "Error opening %s\n", path);
    perror("fopen");
  }
 
  int line_no = 0, fields_current, fields_last, n = 0;
  char buff[MAX_BUFF];
 
  while(fgets(buff, MAX_BUFF, f) && line_no++ < 1000) {
    fields_current = get_fields(buff);
    if(fields_current == fields_last) {
      if(n < 100) {
        *fields = fields_current;
        *start_line = line_no;
        return;
      }
      else {
        n++;
      }
    }
    else {
      n = 0;
    }
    fields_last = fields_current;
  }
 
  *fields = -1;
  *start_line = -1;
  fclose(f);
}

int get_fields(char *s) {
  int fields = 0;
  while(*s) {
    while((*s == ' ' || *s == '\t') && *s)
      *s++;
   
    while(!(*s == ' ' || *s == '\t') && *s)
      *s++;
    fields++;
  }
  return(fields);
}

void split_data(double *data, char *s,  int fields) {
  char buff[DATA_MAX];
  int j = 0, i;

  while(*s) {
    while((*s == ' ' || *s == '\t') && *s)
      *s++;

    i = 0;
    while(!(*s == ' ' || *s == '\t') && *s)
      buff[i++] = *s++;
    buff[i] = 0;

    data[j++] = atof(buff);

    if(j == fields)
      return;
    *s++;
  }
}

Name: KodakGalleryProgrammer 2013-03-31 2:49

What the hell. I haven't been on this board for a really really long time and yet you bitches are still saying my name!

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List