Qbasicnews.com

QBasic => QB Discussion & Programming Help => Topic started by: WaffleMan on June 30, 2006, 01:38:36 AM



Title: PRINT Frustration
Post by: WaffleMan on June 30, 2006, 01:38:36 AM
Hey guys. Sorry the topic's not that descriptive, but it's a small problem that's probably easily fixable but my underdeveloped brain refuses to find an answer.

I'm up in Oregon now on our yearly pilgrimage and for the month up here I'm stuck with a 28800 bps connection, which is why I'm stuck with QB45.

Anyway, I've been trying to rewrite a tiny RPG battle system I made a while back, and this time I'm using TYPES instead of seperate arrays. Well, the problem is this: At the Main Menu, I want to list the player and his HP, and, if he has any party members, their names and their HP. However, I'm having a problem getting them to show up. Here's the code I'm having trouble with:

Code:
FOR j = 1 TO 5
     IF party(j).n <> "" THEN PRINT UCASE$(party(j).n) + ":"; party(j).hp; "HP"
    NEXT j


The declaration, "n", hold's the character's name, and each party array's "hp" declaration holds 50. Unfortunatly, when I run the program, instead of just displaying the player's name and HP, like it's supposed to do, it does this (_ = space):

Quote

<MAIN MENU>
YOU: 50 HP

________________:___50 HP

________________:___50 HP

________________:___50 HP

________________:___50 HP

________________:___50 HP


What's going on here? I thought I wrote the code correctly. I don't recall ever having this problem before. Is there something wrong with the laptop I'm using, or is there just a stupid little mistake I made somewhere that I'm not seeing?

If you want to see the whole code so far, for any reason, here it is:

Code:
'REVAMPED PARTY AND BATTLE SYSTEM
'By Boxtop

DECLARE SUB InitEngine ()

TYPE pim
 n AS STRING * 100
 hp AS INTEGER
 chance AS INTEGER
END TYPE

DIM SHARED party(5) AS pim
DIM SHARED npcs$(100)
DIM SHARED l$(100)

DIM SHARED ttlloc AS INTEGER
DIM SHARED ttlnpc AS INTEGER
DIM SHARED npcask AS INTEGER
DIM SHARED monster AS INTEGER
DIM SHARED plyrHP AS INTEGER

RANDOMIZE TIMER

InitEngine

CLS
PRINT "REMADE PARTY AND BATTLE SYSTEM"
PRINT "BY BOXTOP"
PRINT
1
rndloc% = INT(RND * ttlloc) + 1

CLS
PRINT "<MAIN MENU>"
PRINT
PRINT "PARTY ROSTER:"
PRINT "YOU:"; plyrHP; "HP"
   
   IF party(1).n <> "" THEN
    FOR j = 1 TO 5
     IF party(j).n <> "" THEN PRINT UCASE$(party(j).n) + ":"; party(j).hp; "HP"
    NEXT j
   END IF

PRINT
PRINT "You and your party are currently " + l$(rndloc%) + "."

SUB InitEngine

     OPEN "npc.dat" FOR INPUT AS #1
       DO WHILE NOT EOF(1)
         INPUT #1, ttlnpc

           IF ttlnpc > 100 THEN PRINT "ERROR: FILE npc.dat HAS TOO MANY ENTRIES ( > 100)": END

         FOR npcrt = 1 TO ttlnpc
           INPUT #1, npcs$(npcrt)
         NEXT npcrt
       LOOP
     CLOSE #1

     OPEN "loc.dat" FOR INPUT AS #1
       DO WHILE NOT EOF(1)
         INPUT #1, ttlloc

          IF ttlloc > 100 THEN PRINT "ERROR: FILE loc.dat HAS TOO MANY ENTRIES ( > 100)": END
       
         FOR lcrt = 1 TO ttlloc
           INPUT #1, l$(lcrt)
         NEXT lcrt
       LOOP
     CLOSE #1

     plyrHP = 50
     npcask = INT(RND * 3) + 1
     monster = INT(RND * 6) + 1
     
     FOR i = 1 TO 5
       party(i).hp = 50
     NEXT i
END SUB


Title: PRINT Frustration
Post by: DrV on June 30, 2006, 10:33:28 AM
At first glance, it looks like you aren't initializing party anywhere.  The reason your code prints spaces is that the unused part of fixed-length strings is always filled with spaces.  You can get rid of them when printing, etc. with RTRIM$ or similar.


Title: PRINT Frustration
Post by: Anonymous on June 30, 2006, 11:39:54 AM
yeah,. that is weird though. in the prog he does not assign party(x).n, BUT:

Quote
PRINT "YOU:"; plyrHP; "HP"
   
   IF party(1).n <> "" THEN
    FOR j = 1 TO 5
     IF party(j).n <> "" THEN PRINT UCASE$(party(j).n) + ":"; party(j).hp; "HP"
    NEXT j
   END IF

PRINT


that condition should never be filled; none  of the names should be printed... wtf??


Title: PRINT Frustration
Post by: DrV on June 30, 2006, 11:50:10 AM
It will always be true, because as I said, fixed-len strings are filled with spaces.  If you want that to work, you should do
Code:
IF RTRIM$(party(1).n) <> "" THEN
or something similar.


Title: PRINT Frustration
Post by: Anonymous on June 30, 2006, 11:51:47 AM
OH. >.> That makes sense.

you should also probably do:


Code:
FOR j = 1 TO 5
  IF RTRIM$(party(j).n) <> "" THEN
    PRINT UCASE$(party(j).n) + ":"; party(j).hp; "HP"
  END IF
NEXT j


Title: PRINT Frustration
Post by: WaffleMan on July 01, 2006, 01:48:57 AM
The RTRIM$() trick doesn't work for me. And the only reason I have a fixed length string is that QBASIC complains about a missing "*" when I try to declare a normal string, even though QBASIC's manual implies otherwise. Is there a way I can get around that?


Title: PRINT Frustration
Post by: Anonymous on July 01, 2006, 05:23:02 AM
sure, try this:

Code:
FOR j = 1 TO 5
  IF (party(j).n <> space$(100)) THEN '' space$( lengthOfYourString)
    PRINT UCASE$(party(j).n) + ":"; party(j).hp; "HP"
  END IF
NEXT j


Title: PRINT Frustration
Post by: Phydaux on July 01, 2006, 12:50:04 PM
Wow, I never realised the rtrim didn't trim fixed length strings. (At least ones defined in types anyway). I guess I'm too used to FB and VB. :P


Title: PRINT Frustration
Post by: RyanKelly on July 02, 2006, 06:44:51 PM
Fixed length strings are padded with ascii code 0 (null), rather than ascii code 32 (space).  This is why RTRIM$ and LTRIM$ don't seem to operate properly because they only attempt to remove the space character.

To trim out the null characters, try this cludge (not perfect because if the string is all null characters, this expression returns a string with one null character in it.)


left$(S, instr(S,chr$(0)))
where S is your fixed lenght string.

To test for an empty string try check the condition
instr(s,chr$(0))=1


Example:
assuming sarray is an array of fixed length strings.
Code:

for index=lbound(sarray) to ubound(sarray)
  if not (instr(sarray(index),chr$(0))=1)
     print left$(sarray(index),instr(sarray(index),chr$(0));
   end if
next index


Title: PRINT Frustration
Post by: WaffleMan on July 03, 2006, 12:53:08 AM
Eh, nevermind. I took a shortcut and used a seperate string array. :b


Title: PRINT Frustration
Post by: DrV on July 03, 2006, 12:59:58 PM
Oi, you're right, it is padded with nuls... I must be thinking of something else then.


Title: PRINT Frustration
Post by: Phydaux on July 03, 2006, 06:59:19 PM
Quote from: "RyanKelly"
Fixed length strings are padded with ascii code 0 (null), rather than ascii code 32 (space).  This is why RTRIM$ and LTRIM$ don't seem to operate properly because they only attempt to remove the space character.
Like I said, I'm used to FB and VB. Where the trim functions remove null chars as well as spaces.


Title: PRINT Frustration
Post by: RyanKelly on July 04, 2006, 12:50:13 AM
Quote from: "Phydaux"
Quote from: "RyanKelly"
Fixed length strings are padded with ascii code 0 (null), rather than ascii code 32 (space).  This is why RTRIM$ and LTRIM$ don't seem to operate properly because they only attempt to remove the space character.
Like I said, I'm used to FB and VB. Where the trim functions remove null chars as well as spaces.


ltrim in version .15b of the run time library for FreeBasic uses a runtime lib function to skip over ascii code 32 then copy the remainder of the string.  

My test shows that version .15b of Freebasic behaves the same as QB in this regard.