Code:
/* sample.c from code snippets we use for the exact same purpose sorting
tab-delimited files qsort() is generally more efficient */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DELIMITER "," /* token separator */
#define ARR_SIZE 2500 /* largest possible number of records */
#define BUFSZ 256 /* char in read buffer */
#define FLDS 3 /* fields in struct */
typedef struct {
char lnm[25];
char first[20];
char date[12];
} rec;
void check(int);
int comp(void *, void *);
void parse(char *, rec *,int *);
void tst(FILE *);
void createoffsets(int *,rec *);
void printit(rec *,int);
int main(int argc, char *argv[]){
FILE *in=NULL;
char tmp[BUFSZ]={'\0'};
rec records[ARR_SIZE];
rec *ptr=records;
int count=0;
int offset[7]={0};
tst(in=fopen(argv[1],"r"));
createoffsets(offset,ptr);
while(!feof(in)){
memset(tmp,0x00,sizeof(tmp));
if(fgets(tmp,BUFSZ-1,in)!=NULL){
parse(tmp,ptr++,offset);
check(count++);
}
}
if(fclose(in)==EOF){
perror("Error on input file");
exit(EXIT_FAILURE);
}
qsort(records,count,sizeof(records[0]),comp);
printf("records found:%d\n",count);
printit(records,count);
return 0;
}
void tst(FILE *test){ /* check on file open */
if (test==NULL){
perror("Error opening file");
exit(EXIT_FAILURE);
}
}
void parse(char *tmp, rec *recptr, int *offset){ /* whack string into struct fields */
char *fmt[FLDS+1]={"%24s","%19s","%11s",""};
int i=0, *local=offset;
char *buf, **fmtptr=fmt;
buf=strstr(tmp,"\n");
if(buf)*buf=0x00;
memset(recptr,0x00,sizeof(rec));
for(buf=strtok(tmp,DELIMITER);
buf!=NULL;
buf=strtok(NULL,DELIMITER),local++,fmtptr++){
sprintf(recptr->city + *local,*fmtptr,buf);
}
}
void printit(rec *recs, int count){ /* dump array of structs */
rec *local;
int i=1;
printf("%d records found, sorted by population size:\n",count);
for(local=recs;count;count--,local++)
printf("%22s %2s %8s\n",
local->city,
local->state,
local->population);
}
int comp(void *c, void *d){ /* function for qsort */
rec *a, *b;
a=(rec *)c;
b=(rec *)d;
return strcmp(a->lnm,b->lnm );
}
void createoffsets(int *values, rec *recptr){ /* create pointer offsets for struct */
char *base=recptr->lnm;
char *buf=recptr->first;
*values++=0;
*values++=(int)buf - (int)base;
buf=recptr->date;
*values++=(int)buf - (int)base;
}
void check(int count){ /* check array bounds */
if( ARR_SIZE +1 == count){ /* change this to whatever you need */
printf("Maximum possible number of records read in, aborting\n");
exit(EXIT_FAILURE); /* puke before we core dump */
}
}