All pastes #471271 Raw Edit

parser

public cpp v1 · immutable
·published 2007-05-04 20:21 UTC
rendered paste body
struct G_DATA {    //They're all unsigned because I'm not handling the    //sign on the integer parsing anyway.    unsigned int id;    unsigned int prvID;    unsigned int SCscore;};void parse(FILE* f){    char c;    std::vector<struct G_DATA> data;    struct G_DATA thisdata;    while(!feof(f)) {        c=fgetc(f);        //if the line starts in G, put the character back on the stream and        //call the actual parsing code; otherwise skip the line altogether        if(c == 'G') {            ungetc(c,f);            //this error handling kinda sucks            if (parse_G_DATA(f, &thisdata)) {                data.push_back(thisdata);            } else {                fprintf(stderr, "Parse error\n");                return;            }        } else {            skip_rest_of_line(f);        }    }    //do something useful with the vector now    //...        //cleanup    data.clear();}bool parse_G_DATA(FILE* f, G_DATA* elem){    char header[7]={0};    char c;    int variables_read=0;    int tmp=0;    fread(header,1,6,f);    if(strcmp(header,"G_DATA")) {        //this line doesn't even start with G_DATA, return        //XXX should skip this line instead of giving an error        //on the caller; but for now I'm returning the same        fprintf(stderr, "expected G_DATA, got... something else\n");        return false;    }    skip_whitespace(f);    while(!feof(f)) {        c=fgetc(f);        if(c == '\n') {            fprintf(stderr, "premature end of line\n");            return false;        }        if(isnumeric(c)) {            //Yep, I'm using my own integer parser. I'd use strtol but it's            //not easy to combine it with reading one char at a time...            tmp*=10;            tmp+=c-'0';        } else if(isspace(c)) {            //we probably just hit the end of an integer parsing here            switch(variables_read) {                case 0:                    elem->id = tmp;                    break;                case 1:                    elem->prvID = tmp;                    break;                case 2:                    elem->SCscore = tmp;                    break;                case 3:                    //we (probably) finished!                    skip_rest_of_line(f);                    return true;            }            variables_read++;            //skip the spaces that follow too            skip_whitespace(f);        }    }    return true;}//these two functions need error checking in case we reach EOF!void skip_whitespace(FILE* f){    char c;    do {        c=fgetc(f);    } while(c == ' ' || c == '\t');    ungetc(c, f);}void skip_rest_of_line(FILE* f){    char c;    //skip all characters until we reach a newline    do {        c = fgetc(f);    }    while(c != '\r' && c != '\n');    //now skip any consecutive newline characters    do {        c = fgetc(f);    }    while(c == '\r' || c == '\n');    //put back the first character of line    ungetc(c, f);}