File handling with comments

Started by
6 comments, last by flangazor 19 years, 6 months ago
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_
Advertisement
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
| Stein Nygård - http://steinware.dk |
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:

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]
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
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).
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
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:

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.

Game Programming Blog: www.mattnewport.com/blog

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++;	}}
I know it's off the top of your head, but you also need to check vs. EOF in the most internal while in case the comment is on the last line.

This topic is closed to new replies.

Advertisement