File handling with comments
Hey, im writing a game with a fairly flexible and complex level file format, unfortunately its too much work to write a level editor so the files have to be written by hand. To make this process easier I want to allow for comments in my file, I want the comments to be like the C++ "//" comments. but maybee just with the sybol '#'.
Ok, so there are two basic tasks i need to preform on my file, read filenames (i need a getline funtion), and read numbers (i need a get token function)
So for the get token function i was thinking of making a wrapper function for scanf, where the arguements are the same as scanf ---- void GetToken(FILE* fp, const char* control, ?????? adress);
and in that function will be a scanf(fp, control, adress); as well as checking for the comment. But what i dont know, is what to put as the last argument for the wrapper function so that it will work for more than one type of number, maybee void*?
If you can help me with this, or an easier way to do it i would be very appreciative. Thanks
_Phalanx_
AFAIK you can't repass variable argument-lists, which is what you would wanna do... If it was possible, you could have a nice function like this:
void GetToken(FILE* fp, const char* control, ...);
I'm very interested if anyone knows how to do this though!
An alternative is to template or overload your function, for different types :)
regards
void GetToken(FILE* fp, const char* control, ...);
I'm very interested if anyone knows how to do this though!
An alternative is to template or overload your function, for different types :)
regards
what i would do (and its what i've done several times for my shader parser, BASIC compiler, and numerous other projects) is load the entire file into some dynamic memory and just work with pointers.
here is a skeleton C++ implementation:
that is totaly off the top of my head (see how many times i've used it :D - use at own risk and i dont even know if it compiles, hope you get the idea though!
[Edited by - silvermace on October 14, 2004 9:09:37 PM]
here is a skeleton C++ implementation:
class TokenStream{public: char *data; char *end; char *cur;public: // load the data to local storage void load( char * _data, int len ) { if( data ) delete [] data; data = new char[len+1]; memcpy( data, _data, len ); data[len] = 0; // for safety checking end = data + len; } // get the next token char *getNextToken() { // temp buffer static char buf[256]; memset(buf, 0, 256); while( iswspace( *cur ) != 0 ) cur++; // skip comments if( *cur == '/' && cur+1 < end ) { if( cur+1 == '/' && cur < end ) { while( *cur != '\n' ) cur++; } } char *p = buf; while( cur < end && isDelim( *cur ) != 0 ) { *p++ = *cur++; } // oopss.... if( cur > end ) return NULL; return buf; } // check for delimiters bool isDelim( char _c ) { if( _c == ' ' || _c == ',' ) return true; return false; }};
that is totaly off the top of my head (see how many times i've used it :D - use at own risk and i dont even know if it compiles, hope you get the idea though!
[Edited by - silvermace on October 14, 2004 9:09:37 PM]
If I were you I'd ditch the idea of varargs for something like a stream concept. You get type safety and can use notation such as >> to make it easy to write. I consider streams to be extremely important in properly parsing things nowadays -- particularly if you make the stream watch for exceptional circumstances itself (over/underflow).
yeah, i shoudl learn about streams one of these dayds, but now, i found a crude but working method. Im trying to get this game im doing done. i could improve it forever :|.
for those of you that are interested, heres my solution:
for those of you that are interested, heres my solution:
void GetToken(FILE* fp, const char* control, void* adress);void Direct3D::GetToken(FILE* fp, const char* control, void* adress){ char c; while((c = getc(fp)) != 'EOF'){ if(iswspace(c)) continue; if(c == '#'){ while((c = getc(fp)) != 'EOF' && c != '\n'){} }else{ --fp->_ptr; fscanf(fp, control, adress); break; } }}
You should look at Lex and Yacc (or Flex and Bison as the GNU versions are known) - whilst they take a bit of effort to learn they will pay off big time when you want to add new features to your file format and it starts to get more complex.
You CAN repass variable arguments. Here's how:
void Direct3D::GetToken(FILE *fp, const char *control, ...){ va_list args; va_start(args, control); vfscanf(fp, control, args); // Note the 'v' in front of the function name va_end(args);}
// skip commentsif( *cur == '/' && cur+1 < end ) { if( cur+1 == '/' ) { while( *cur != '\n' /* && *cur != '\0' */) cur++; }}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement