Bizarre Error in my Script Interpreter

Started by
6 comments, last by 3DNeophyte 19 years, 7 months ago
Ok, this has been driving me mad for two days now so I'm turning to you guys for help and/or suggestions. What I have is a text-RPG "engine" that is controlled by a script interpreter that I'm writing. Here's a simple sample script:

//output: "a = 10"
main()
{
  var int a = 5 ;
  var double b = 4.5 ;
  set a 10 ;
  prt ' a = &a '
}
This works just fine. However, I was messing around with printing two variables in a string, and when I used a particular string, an unusual anomaly occurred. This is the script I wrote:

//nevermind the poor grammar in prt() - I was being silly :)
main()
{
  var int a = 3 ;
  var double b = 4.5 ;
  prt ' this &a and &b is high '
}
That script should've output "this 3 and 4.5 is high " , but the actual output was this: 4.5 . Instead of printing the string, it printed the value portion of the previous var() statement. I was perplexed. After doing some thinking, I increased the length of the string by one by changing 'is' to 'isa' . And to my amazement, it worked just fine: "this 3 and 4.5 isa high ". So I counted up the number of characters in the offending string, which came out to be 26 characters. So I typed in some random 26 character string and voila! .... it output the same error: 4.5 . So I did some investigating. To make a long story sweet and short, the error is triggered in the deserialization of the prt() function within my script-command stack. The offending code is this:

/*iext is an int, parm is a fixed-length string (no overflow)*/
fread((int*)&iext, sizeof(int), 1, fp);
fread((char*)parm, sizeof(char), iext, fp);



When this code attempts to read in the 26 character string, it fails to read the integer in the first fread(), which is supposed to be 26. I checked the return value, which was zero - so it didn't even read anything. If the length of the string is greater than or less than 26, it always works fine. I can't figure this out. If anyone has any suggestions as to what "might" be happening, please let me know. If more information or code is needed, just ask. Thank you :) [Edited by - 3DNeophyte on September 16, 2004 9:51:06 PM]
Advertisement
I'm willing to discuss and explain anything concerning my interpreter - how it works, how it's organized, etc. Just ask anything about it, and I'll be happy to explain.
Did you open the file in binary mode?

Now that I think about it, 26 might be the ASCII code for EOF... that int would be stored as: 0 0 0 26 (bytewise) which would mean your program thinks the file has ended, and thus it isn't reading anything more, and it's instead leaving the old values of those variables in those functions.

fopen( "filename" , "rb" );


edit: I looked it up. 26 is indeed EOF. This is why I hate windows compilers. On all the unix based systems, it by default opens with binary mode (the extra b has no effect on these systems).
Yes, the reading and writing is in binary. 26 might be the value for EOF? Hmmmm, I'll run a test on that. Thanks, Maul.
"is in binary" - did you mean the values are binary (obvious) or the file open commands?

If the 1st, setting up the 2nd should fix it. If you meant the 2nd, can you post your fopen calls?

And no prob ^_^.
I ran this script:

main(){  var int a = 26 ;  prt ' a = &a '}


It printed "a = 26" . But then I ran this one:

main(){  var int aaaaaaaaaaaaaaaaaaaaaaaaa = 26 ;  prt ' a = &a '  var double c = 10.332 ;  var int e = 3 ;  prt ' this &a and &c is high '}


When the var() function was processed, it failed. So 26 IS a magic number, and I only thought I was joking with my friend about that :p . Ok, I'll have to find a way around this. Thank you, Maul!
Sorry, my cable just went out -- Ivan's been tearing up the city. Anyway, here's my fopen call and write calls:

FILE* fp = fopen(savefile, "wb");/* .... other random stuff .... */fwrite((int*)&p->fid, sizeof(int), 1, fp);fwrite((int*)&p->nparms, sizeof(int), 1, fp);for (int i = 0; i < p->nparms; i++){	strcpy(parm, p->parms);	size = strlen(parm) + 1;	fwrite((int*)&size, sizeof(int), 1, fp);	fwrite((char*)parm, sizeof(char), strlen(p->parms) + 1, fp);	}


So am I correct in assuming the 26 is applicable in this case?
I'm bowing my head in shame as I write this. I looked at my fopen() call for the reading section. And guess what ...... I found this: fopen(savefile, "r") !!!!! Something so small, yet so critical. Changed to "rb" and all is well. Still, I wouldn't have noticed that if you hadn't mentioned the binary situation. Thanks again for your help, Maul - I greatly appreciate it!

This topic is closed to new replies.

Advertisement