|
|||||||
This is a discussion on "File I/O problems" in the Top Mud Sites MUD Coding forum : I'm restructuring OLC a bit, and in the process I've created a new editor type, which I'm putting into a new .are file. The problem is, I'm getting very odd error messages from bug, to the tune of "Can't find the corrent information from line 0 of your file." This is true because there IS no line 0 of that file. Any reason this code would be looking for line 0 instead of line 1 to start out with? Are there any other things wrong with the code that I can't see ... |
|
You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our MUD community today! If you have any problems with the registration process or your account login, please contact us. If you are a registered member of the old TMS forums, please click here
|
![]() |
|
|
LinkBack | Thread Tools |
|
|
#1 |
|
Member
|
I'm restructuring OLC a bit, and in the process I've created a new editor type, which I'm putting into a new .are file. The problem is, I'm getting very odd error messages from bug, to the tune of "Can't find the corrent information from line 0 of your file." This is true because there IS no line 0 of that file. Any reason this code would be looking for line 0 instead of line 1 to start out with? Are there any other things wrong with the code that I can't see because I'm blind?
-------------------------------------------- void load_segments( FILE *fp ) { SEG_DATA *pSeg; char *word, line[128]; int i, j; fgets(line, sizeof(line), fp); word = fread_word(fp); if (!str_cmp(word, "Segments")) i = fread_number(fp); else bug("ERROR: Number of Segments not defined.", 0); for (j = 0; j < i; j++) { pSeg = alloc_perm(sizeof(pSeg)); pSeg->vnum = j; pSeg->name = fread_string(fp); pSeg->builders = fread_string(fp); pSeg->seg_flags = fread_number(fp); pSeg->credit = fread_string(fp); } fclose(fp); } ----------- I should be adding to this function, especially since this'll end up a linked list, but for now since I only have one segment, wth? -Visko |
|
|
|
|
|
#2 |
|
Member
Join Date: Sep 2002
Location: Canada
Posts: 73
![]() |
I suspect it has something to do with intermixing standard C library file functions fgets - which doesn't increment the mud's line number variable - with mud file library routines fread_xxx which do.
Questions to ask yourself: - is the .are file actually opened? by routines which initialize the line number? - why are you fgetsing into a buffer called line, then never using it? To help you figure out which fread_xxx() call is causing the bug message, insert your own test bug messages before and after the calls to fread_number() so that you can recognize where the program is. bug("Test: Before the fgets"); bug("Test: Between fgets and fread"): etc. After the problem is diagnosed and solved, you remove the test bugs. Hope this helps. |
|
|
|
|
|
#3 |
|
Member
|
I've done all those things so far; the function in question is called by boot_db which runs through area.lst, a file that has the file-names of all of the current files to be loaded into the MUD. I know it opens up segment.are, but I'm not sure how it opens it; that's a very good question.
I've already stepped through this function with gdb, but I suppose I did that before I started getting this message. I'll post another reply after I step through it again, and hopefully it'll be to thank you because I figured out what was wrong! Thanks, -Visko |
|
|
|
|
|
#4 |
|
Member
|
Ok, this is weird. I'm gonna copy the log of what I did with gdb, and maybe someone'll understand wth is going on, because I sure don't...
(gdb) break load_segments Breakpoint 1 at 0x8070f1d: file db.c, line 414. (gdb) run 8001 Starting program: /mnt/big/home/visko/Slugs/src/prism 8001 Breakpoint 1, load_segments (fp=0x80d8c40) at db.c:414 414 fgets(line, sizeof(line), fp); (gdb) next 415 word = fread_word(fp); (gdb) next 416 if (!str_cmp(word, "Segments")) (gdb) print word $1 = 0x80c3820 "Segments" (gdb) next 417 i = fread_number(fp); (gdb) next 420 for (j = 0; j < i; j++) (gdb) print i $2 = 1 (gdb) next 422 pSeg = alloc_perm(sizeof(pSeg)); (gdb) next 423 pSeg->vnum = j; (gdb) next 424 pSeg->name = fread_string(fp); (gdb) 425 pSeg->builders = fread_string(fp); (gdb) print pSeg->name $3 = 0x4016d503 "Stock Prism Area" (gdb) next 426 pSeg->seg_flags = fread_number(fp); (gdb) print pSeg->builders $4 = 0x4016d518 "Visko Meric" (gdb) next 427 pSeg->credit = fread_string(fp); (gdb) print pSeg->seg_flags $5 = 0 (gdb) next 420 for (j = 0; j < i; j++) (gdb) print pSeg->credit $6 = 0x4016d528 "[Stock Segment for Prism Startup]" (gdb) next 429 fclose(fp); (gdb) 430 } (gdb) boot_db () at db.c:317 317 } (gdb) 292 if ( fread_letter( fpArea ) != '#' ) (gdb) 294 bug( "Boot_db: # not found.", 0 ); (gdb) Tue Jan 14 00 Tue Jan 14 00 295 exit( 1 ); (gdb) Program exited with code 01. (gdb) Everything loaded fine. Then it went back to the parent function and tried to load the file AGAIN...but in a weird way. Any clue as to what's up? -Visko |
|
|
|
|
|
#5 |
|
Member
Join Date: Sep 2002
Location: Canada
Posts: 73
![]() |
Yes, I see it.
The gdb line 429 shows you fclosing the file. Then on line 292 you try to fread_letter (expecting a '#' Reading from closed files is a no-no. Delete the fclose(fp) in function load_segments(). This is your problem. |
|
|
|
|
|
#6 |
|
Member
|
Figured it out. As crazy as this seems, the end of the file requires #$ instead of just $ because boot_db reads # first, then checks for the operative, which in the case of $, means move on to the next file.
What a crock. Thanks for everything though, everything you suggested definitely put me on the right track So many thanks, this one has been ****ing me off for days, -Visko |
|
|
|
|
|
#7 |
|
Member
Join Date: Sep 2002
Location: Canada
Posts: 73
![]() |
Glad I could help.
Here's a tip to avoid future woes: have your file opens and file closes in the same higher-level routine, with calls to the section reading routines in the middle. Its cleaner, and you avoid unnecessary (and sometime unexpected) side-effects. |
|
|
|
|
|
#8 |
|
Member
|
Ok, well it reads. But my problems haven't ended. I tried editing the segment I loaded, and it didn't work. On a whim, I threw in a function that listed the current loaded segments. This is what I got:
<1500/1500hp 900/900mv> slist [Num] [Seg Name ] (Builders) [Credit ] [1076573508] (null) (null) [1076573532] (null) @6+@ (Please ignore the bad spacings; I'm cleaing that up later, this was just a hack from alist.) As you can see, the numbers are a tad wrong (they should start at 1 and move upwards from there...), and the names/builders/credits are just...off. And I don't know why. Does this kind of screwup look familiar to anyone? Thanks so much, I'll post any other code people want to see to get to the bottom of this. -Visko |
|
|
|
|
|
#9 |
|
Member
Join Date: Sep 2002
Location: Canada
Posts: 73
![]() |
It doesn't look like you are printing your data, you have a bad or missing pointer to your information. To know more, I'd need to see the line(s) before and upto the line that printed that display.
I also noticed that in your original function you allocate a structure, keep a pointer to it in the variable pSeg, read your strings from the file and then exit. But no other function can reference this data, since the variable pSeg disappears when load_segments() returns. |
|
|
|
|
|
#10 |
|
Member
|
Right, sorry, I was getting ahead of myself. Let me repost some of the functions, they've changed a bit. There's a few other things to show, as well, I suppose...
void load_segments( FILE *fp ) { SEG_DATA *pSeg; char *word, line[128]; int i, j; fgets(line, sizeof(line), fp); word = fread_word(fp); if (!str_cmp(word, "Segments")) i = fread_number(fp); else bug("ERROR: Number of Segments not defined.", 0); for (j = 1; j <= i; j++) { pSeg = alloc_perm(sizeof(pSeg)); pSeg->vnum = j; pSeg->name = fread_string(fp); pSeg->builders = fread_string(fp); pSeg->seg_flags = fread_number(fp); pSeg->credit = fread_string(fp); if ( seg_first == NULL ) seg_first = pSeg; if ( seg_last != NULL ) seg_last->next = pSeg; seg_last = pSeg; pSeg->next = NULL; top_seg++; } } That's the loading function; seg_first and seg_last are globally defined. The listing function is the following: void do_slist( CHAR_DATA *ch, char *argument ) { char buf [ MAX_STRING_LENGTH ]; char result [ MAX_STRING_LENGTH*2 ]; /* May need tweaking. */ SEG_DATA *pSeg; sprintf( result, "[%3s] [%-27s] (%-8s) [%-10s]\n\r", "Num", "Seg Name", "Builders", "Credit" ); for ( pSeg = seg_first; pSeg; pSeg = pSeg->next ) { sprintf( buf, "[%3d] %-29s %-5s %-12s\n\r", pSeg->vnum, pSeg->name, pSeg->builders, pSeg->credit); strcat( result, buf ); } send_to_char( result, ch ); return; } Segment structure is the following: /* * Segment definition. Work in progress. --Visko */ struct segment_data { SEG_DATA * next; char * name; char * builders; int seg_flags; char * credit; int vnum; }; Lesse, anything else.... I think that's about it for loading and displaying. If there's anything else you need, or anything obviously wrong, just post and I'll do what I can. Thanks, -Visko |
|
|
|
|
|
#11 |
|
Member
Join Date: Sep 2002
Location: Canada
Posts: 73
![]() |
Okay, still your biggest problem is in load_segments. But just to make you feel better, you also have little problems there too!
The biggest problem is that your variable pSeg is a pointer (about 4 bytes long on most machines). alloc_perm(sizeof(pSeg)) will allocate the smallest grain that will hold 4 bytes. This is not what you want. Try using sizeof(SEG_DATA) which is my preference, or else the also-correct-but-leaves-me-with-a-queasy-feeling-in-my-gut: sizeof(*pSeg) Little problem #1 I still don't see why you fgets() to read in line[], but if you insist on not using what you read, how about putting a one line comment after the fgets(), saying you are ignoring the line. Little problem #2 How about some reasonability checks on the result of... i = fread(number); ...which is your loop limit. A corrupt file can send you looping or out of memory without even so much as a hint in the logfile. Bigger problem: In do_slist you perform a needlessly dangerous act of doing wishful strcat() into result[], while praying that there weren't too many found by load_segments. As soon as there are too many - boom. Instead of strcating individual lines into result, just use send_to_char(buf,ch) and forget about using result[] altogether. Less is more. |
|
|
|
|
|
#12 |
|
Member
|
*slaps self*...
Thanks for catching the *pSeg thing. I changed it to SEG_DATA like you advised, because you said it was a good idea of course, and also because it'll remind me later on not to make the same mistake if/when I start doing something like this again. I also used send_to_char instead of compiling a huge buffer and sending it out all at once; I hadn't really thought about the possibility of going over max_string_length, but I suppose that it could easily be possible if I start getting insane quantities of segments, so I think you may have just given me great wisdom Segments load and work, I think I've got my file I/O problems worked out finally, and I can go screw up the next part of the implementation with the happy knowledge that I may yet get it right Thank you so much, -Visko |
|
|
|
![]() |
| Thread Tools | |
File I/O problems - Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Problems compiling SMAUG | dalalphabet | MUD Administration | 2 | 02-17-2004 10:34 PM |
| problems with smaug 1.4 objects | Shao_Long | MUD Builders and Areas | 5 | 07-05-2002 02:16 PM |
| Connect/Disconnect Problems | Skorpian | MUD Coding | 2 | 06-28-2002 11:43 PM |
|
|