Qbasicnews.com

QBasic => QB Discussion & Programming Help => Topic started by: joey7643 on February 13, 2003, 07:28:47 PM



Title: If I could bother you guys once again...
Post by: joey7643 on February 13, 2003, 07:28:47 PM
...for two issues:

(I appreciate all of the help you guys have given me!)

1) When displaying the contents of a directory in QB (C:\Program Files\, for example) where the number of files exceeds the number QB can display on screen, how would you display like 20 files, then print a message saying "Press <enter> to see the next 20 files..."? I am thinking something along the lines of a FOR...NEXT loop, but to no avail, I cannot think up a solution.

2) When I have dimmed a variable (such as DIM Variable1 AS STRING *100), and when I enter characters that are less than 100, the variable returns a REDO? error. I would like it so that you could enter up to and including 100 characters in that one variable without receiving an error message.

I have tried both of these problems on my own; I cannot seem to come to a single solution for any one of them.

Thanks for any help you could possibly give me.


Title: If I could bother you guys once again...
Post by: NovaProgramming on February 13, 2003, 07:43:14 PM
Yeah, it's possible, hmm.  I think that you should wait till na_th_an gets on cause he's the one who knows about stuff like that more.  However, i'm sure there's a way.  i thinks it might have something to do with saving the 'dir' command to a .txt file and then reading that bit by bit, if you know what I mean.  anyway, na_th_an will talk to you cause he's awesome.


Title: If I could bother you guys once again...
Post by: joey7643 on February 13, 2003, 11:03:38 PM
Yeah, I figured he might.  :D


Title: If I could bother you guys once again...
Post by: Dav on February 13, 2003, 11:30:14 PM
Well, I don't know how you're doing the file listing, so my help may not be any help at all to you - but I'll try...

If you're using the FILES statement, FILES "filespecs", then no, I don't think you can pause the output like you asked.  And if you are using FILES at all be sure you also use some sort of error trapping, because if you do a FILES on a file spec that doesn't exist, then it will produce an error 53 and your program will halt right there.

You could maybe use the DOS command DIR, called by QB's SHELL statement and specify the /p parameter that pauses the output that way(like DIR *.* /p), or perhaps even redirect the output to a file and read the files that way (DIR *.* > files.txt).  Some people around here have written some good examples of using DIR that way and I'm sure would be happy to give it to you.

- Dav


Title: If I could bother you guys once again...
Post by: na_th_an on February 14, 2003, 09:02:48 AM
To stop and wait for a keypress each 20 lines just add a counter of lines:

Code:
t$="C:\WINDOWS"
SHELL "dir "+t$+" /b >list.txt"
counter% = 0
CLS
OPEN "list.txt" FOR INPUT AS #1
WHILE NOT EOF(1)
   LINE INPUT #1,line$
   PRINT line$
   counter%=counter%+1
   IF counter%=21 THEN
      counter%=0
      PRINT "Any key ... ": SLEEP: k$=INKEY$
      CLS
   END IF
WEND
CLOSE 1
PRINT "EOF"


Title: If I could bother you guys once again...
Post by: red_Marvin on February 14, 2003, 11:04:11 AM
Code:

SHELL "dir/p"


Title: I don't understand your problem with the STRING*100...
Post by: Glenn on February 14, 2003, 12:17:13 PM
variable.  Are you saying something like the following doesn't work?

DIM V AS STRING*100
LINE INPUT V
PRINT V
END

(I input "HELLO" at the prompt for V and everything worked just fine.)


Title: If I could bother you guys once again...
Post by: Hexadecimal Disaster on February 14, 2003, 05:20:29 PM
Someone forgot to include the puppy-eyes tag on their post, eh Nova? (http://www.handykult.de/plaudersmilies.de/biglaugh.gif)

Mr. wildcard has this pretty interesting code floating around here to avoid the use of SHELL for directory listing, the funny thing is that it seems that he forgot it... WHY you didn't mention it? (http://www.handykult.de/plaudersmilies.de/sad/bored.gif)

Code:
'DIR.BAS by Dave Cleary
'
'One of the most useful additions to BASIC 7 PDS is the DIR$ function.
'This function allows you to read a directory of filenames. It also
'allows you to check the existence of a file by doing the following:
'
'  IF LEN(DIR$("COMMAND.COM")) THEN
'     PRINT "File Found"
'  ELSE
'     PRINT "File not found"
'  END IF
'
'Now QuickBASIC 4.X users can have this useful function for their
'programs.
'
'Calling DIR$ with a FileSpec$ returns the the name of the FIRST
'matching file name. Subsequent calls with a null FileSpec$ return the
'NEXT matching file name. If a null string is returned, then no more
'matching files were found. FileSpec$ can contain both a drive and a
'path plus DOS wildcards. Special care should be taken when using
'this on floppy drives because there is no check to see if the drive
'is ready.

DEFINT A-Z

DECLARE FUNCTION DIR$ (FileSpec$)

'$INCLUDE: 'QB.BI'

'-----  Some constants that DIR$ uses
CONST DOS = &H21
CONST SetDTA = &H1A00, FindFirst = &H4E00, FindNext = &H4F00

'--------------------------------------------------------------------
'This shows how to call DIR$ to find all matching files

CLS
FileSpec$ = "C:\QB\*.*"
Found$ = DIR$(FileSpec$)
DO WHILE LEN(Found$)
   PRINT Found$
   Found$ = DIR$("")
LOOP

'--------------------------------------------------------------------

FUNCTION DIR$ (FileSpec$) STATIC

   DIM DTA AS STRING * 44, Regs AS RegTypeX
   Null$ = CHR$(0)

'-----  Set up our own DTA so we don't destroy COMMAND$
   Regs.AX = SetDTA                    'Set DTA function
   Regs.DX = VARPTR(DTA)               'DS:DX points to our DTA
   Regs.DS = -1                        'Use current value for DS
   InterruptX DOS, Regs, Regs          'Do the interrupt

'-----  Check to see if this is First or Next
   IF LEN(FileSpec$) THEN              'FileSpec$ isn't null, so
   'FindFirst
FileSpecZ$ = FileSpec$ + Null$   'Make FileSpec$ into an ASCIIZ
   'string
Regs.AX = FindFirst              'Perform a FindFirst
Regs.CX = 0                      'Only look for normal files
Regs.DX = SADD(FileSpecZ$)       'DS:DX points to ASCIIZ file
Regs.DS = -1                     'Use current DS
   ELSE                                'We have a null FileSpec$,
Regs.AX = FindNext               'so FindNext
   END IF

   InterruptX DOS, Regs, Regs          'Do the interrupt

'-----  Return file name or null
   IF Regs.Flags AND 1 THEN            'No files found
DIR$ = ""                        'Return null string
   ELSE
Null = INSTR(31, DTA, Null$)     'Get the filename found
DIR$ = MID$(DTA, 31, Null - 30)  'It's an ASCIIZ string starting
   END IF                              'at offset 30 of the DTA

END FUNCTION


Adapt the previous code by Mr. Na_th_an and you'll get something beautiful... oh, talking about Na_th_an, he's also writes poetry... (dejándose de leseras, ¿quién mierda escribió esto? Merece un premio)

Quote
###########################################
* Desconocido, Probablemente    [el 15 de febrero de 2003 ]
###########################################

..the uno quién escribe esta poesía no es
..the uno que nombre aparece sobre
..the uno quién escribe esto piensa que
..the uno quién fijó que esto debe pensar primer
..the uno quién fija estos poemas consigue
..the corregido uno quién los postes como esto consiguen comprobó
..the uno ahora ha hablado




AOOOOOHHH!! *howls of heavy laughter* (http://www.handykult.de/plaudersmilies.de/rofl.gif)


Title: If I could bother you guys once again...
Post by: na_th_an on February 14, 2003, 05:34:40 PM
JEJEJEJEJJEE --- Quita eso de ahí, hombre, que hay niños y se nos mosquean los jefes ;)

Eso lo escribimos entre unos cuantos una noche de mucha cerveza y mucha maría... ¿cómo carajo lo has encontrado?


AJAJAJAJAJAJAA


Title: If I could bother you guys once again...
Post by: Hexadecimal Disaster on February 14, 2003, 05:42:16 PM
No importa, porque aún los que piensan que saben leer español no deben tener ni la más puta idea de la terminología utilizada... (http://www.handykult.de/plaudersmilies.de/biglaugh.gif)

So... kudos for you and your friends. (http://www.handykult.de/plaudersmilies.de/happy/xyxthumbs.gif)


Title: If I could bother you guys once again...
Post by: na_th_an on February 14, 2003, 06:25:22 PM
He he - Thanks man.


Title: Ich spreche nur Englisch.
Post by: Glenn on February 14, 2003, 07:30:37 PM
.


Title: If I could bother you guys once again...
Post by: Hexadecimal Disaster on February 14, 2003, 08:38:10 PM
Kazhdy drochit kak on khochet. Often poetry loses intensity when translated, so...  :roll:


Title: If I could bother you guys once again...
Post by: Piptol on February 15, 2003, 12:01:04 AM
Quote from: "Hexadecimal Disaster"
No importa, porque aún los que piensan que saben leer español no deben tener ni la más puta idea de la terminología utilizada... (http://www.handykult.de/plaudersmilies.de/biglaugh.gif)

So... kudos for you and your friends. (http://www.handykult.de/plaudersmilies.de/happy/xyxthumbs.gif)


Well, some people understand more than you think.. and if you'd written that in English you'd most likely have got banned from the forum...

..so does that make it right?  :-?


Title: If I could bother you guys once again...
Post by: Hexadecimal Disaster on February 15, 2003, 01:11:42 AM
Maybe. Feel free to send me your translation via PM so I can tell you your score. And if I'd written that in English, the poem would not rhyme.  :roll:


Title: If I could bother you guys once again...
Post by: relsoft on February 15, 2003, 02:56:24 AM
This word is somehow very disturbing....

"masturba "

LOL


Title: If I could bother you guys once again...
Post by: Antoni Gual on February 15, 2003, 07:50:57 AM
Programmer, musician, poet... Nathan, you are really a renassaince man! :rotfl:
Could you put music to your poem?


Title: If I could bother you guys once again...
Post by: na_th_an on February 15, 2003, 11:10:10 AM
Hahahahaha - Nope, that poem is conceived to be sang without music and standing dressed like Shakespeare in the top of a big can full of beer.


Title: If I could bother you guys once again...
Post by: joey7643 on February 15, 2003, 12:12:04 PM
I have figured out my problem with my second question. However, I have been trying a while to get an error-message system working in my program for sometime. How would I setup something that when an error occurs (say error #54) I would like a message to display "Bad file mode."

I have looked through many examples, but I can't seem to get it working.

Thanks again, also for your help with my first problem/question. I have it working now.


Title: What's wrong with QB's error handler?...
Post by: Glenn on February 15, 2003, 12:37:02 PM
It's  going to detect things like that before your error handler gets to it anyway.


Title: If I could bother you guys once again...
Post by: Piptol on February 15, 2003, 12:39:05 PM
Quote from: "Hexadecimal Disaster"
And if I'd written that in English, the poem would not rhyme.  :roll:


Maybe not, but this does: ;)

Hex posted vulgarities,
In a language few understand,
But wildcard had learnt spanish,
And *somebody* got banned!


Title: If I could bother you guys once again...
Post by: na_th_an on February 15, 2003, 01:34:32 PM
Quote from: "joey7643"
I have figured out my problem with my second question. However, I have been trying a while to get an error-message system working in my program for sometime. How would I setup something that when an error occurs (say error #54) I would like a message to display "Bad file mode."

I have looked through many examples, but I can't seem to get it working.

Thanks again, also for your help with my first problem/question. I have it working now.


Well, just add an ON ERROR to your code (this is something that I dislike, but well).

At the top:

Code:
ON ERROR GOTO errorhandler


And somewhere:

Code:
errorhandler:
PRINT "Error number : "; ERR
PRINT "Press a key": SLEEP: k$=INKEY$
RESUME NEXT


I dislike this 'cause it makes your EXE a lot bigger and slower. But if you are not in a speed-intensive application (i.e. a game) then it is ok ;)


Title: If I could bother you guys once again...
Post by: joey7643 on February 16, 2003, 10:56:26 AM
Thanks, that is what I needed na_th_an.

Thank you all for your help  :D  :)


Title: If I could bother you guys once again...
Post by: Antoni Gual on February 16, 2003, 05:08:50 PM
ON ERROR only makes the app slower where it's activated. If you put an ON ERROR GOTO 0 past the part where you need the errors to be trapped, your overall code will not suffer from lack of speed.


Title: If I could bother you guys once again...
Post by: na_th_an on February 16, 2003, 05:11:55 PM
Nice to know, Antoni... err

How do you know ALL THAT STUFF?? :D (should I RTFM??)


Title: If I could bother you guys once again...
Post by: Antoni Gual on February 16, 2003, 05:31:56 PM
I ask Glenn, the only one who has TFM  :D

(Now seriously: I think I read  it at Ethan Winer's book.)


Title: If I could bother you guys once again...
Post by: na_th_an on February 16, 2003, 07:16:24 PM
I downloaded that book a whole lot ago... Maybe I should RTFEWB... (new acronym)


Title: If I could bother you guys once again...
Post by: Neo on February 17, 2003, 07:17:20 AM
Perhaps... (RTFM? NO!!! Even I knew that LoL)


Title: If I could bother you guys once again...
Post by: Hexadecimal Disaster on February 18, 2003, 01:09:40 AM
Kinda late, but... I had some life to live. (http://www.handykult.de/plaudersmilies.de/devil/diablotin.gif)



Quote from: "from Mr. Ethan Winer's book"
The conventional way to handle errors is to use ON ERROR, and design an error handling subroutine. There are a number of problems with using ON ERROR, and most professional programmers try to avoid using it whenever possible. But ON ERROR does work, and it is often the simplest and most direct solution in many programs. The short listing below shows the minimum steps necessary to implement an error handler using ON ERROR.

Code:
ON ERROR GOTO HandleErr
FILES "*.XYZ"
END
HandleErr:
SELECT CASE ERR
CASE 53: PRINT "File not found"
CASE 68: PRINT "Device unavailable"
CASE 71: PRINT "Disk not ready"
CASE 76: PRINT "Path not found"
CASE ELSE: PRINT "Error number"; ERR
END SELECT
RESUME NEXT

The statement ON ERROR GOTO HandleErr tells BASIC that if an error occurs, the program should jump to the HandleErr label. Without ON ERROR, the program would display an error message and then end. Since it is unlikely that you have any files with an .XYZ extension, BASIC will go to the error handler when this program is run. Within the error handling routine, the program uses the ERR function to determine the number of the error that occurred. Had line numbers been used in the program, the line number in which the error occurred would also be available with the ERL function. In this brief program fragment, the most likely error numbers are filtered through a SELECT CASE block, and any others will be reported by number. Regardless of which error occurred, a RESUME NEXT statement is used to resume execution at the next program statement. RESUME can also be used with an explicit line label or number to resume there; if no argument is given BASIC resumes execution at the line that caused the error. In many cases a plain RESUME will cause the program to enter an endless loop, because the error will keep happening repeatedly. In this case, the file will not exist no matter how many times BASIC tries to find it. Therefore, a plain RESUME is not appropriate following a "File not found" or similar error. Had the error been "Disk not ready", you could prompt the user to check the drive and then press a key to try again. In that case, then, RESUME would make sense.

Although BASIC's ON ERROR can be useful, it does have a number of inherent limitations. Perhaps the worst problem with ON ERROR is that it often increases the program's size. When you use RESUME NEXT, you must also use the /x compile switch. Unfortunately, /x adds internal address labels to show where each statement begins, so the RESUME statement can find the line that caused the error. These labels are included within the compiled code and therefore increases its size.

Another problem with ON ERROR is that it can hide what is really happening in a program. I recommend strongly that you REM out all ON ERROR statements while working in the QuickBASIC editing environment. Otherwise, an Illegal function call or other error may cause QuickBASIC to go to your error handler, and that handler might ignore it if the error is not one you were expecting and testing for. If that happens and your program uses RESUME NEXT, you might never even know that an error occurred!

Yet another problem with ON ERROR is that it's frankly a clumsy way to program. Most languages let you test for the success or failure of the most recent operation, and act on or ignore the results at your discretion. Pascal, for example, uses the IOResult function to indicate if an error occurred during the last input or output operation.

Finally, BASIC generates errors for many otherwise proper circumstances, such as the FILES statement above. You might think that if no files were found that matched the .XYZ extension given, then BASIC would simply not display anything. Indeed, an important part of toolbox products such as Crescent Software's QuickPak Professional (shameless plug, eh? - Hex) are the routines that replace BASIC's file handling statements. By providing replacement routines that let you test for errors without an explicit ON ERROR statement, an add-on library can help to improve the organization of your programs.


And now the interesting part:

Quote
As I mentioned earlier, some errors can be avoided by using CALL Interrupt to access DOS directly. (One important DOS service lets you see if a file exists before attempting to open it.) But critical errors such as those caused by an open drive door require assembly language. In Chapter 12 you will learn how to bypass BASIC and access DOS directly using CALL Interrupt.



*breathes deep*


Now, back off topic:

Quote from: "Pipster"
Maybe not, but this does:  

Hex posted vulgarities,
In a language few understand,
But wildcard had learnt spanish,
And *somebody* got banned!


No sir, that doesn't rhyme. Ask Plasma357 for some music lessons. (he composed a nice rhyme about me at the old QB45 forum) And smile. Keep smiling. (http://www.handykult.de/plaudersmilies.de/evilgrinblack.gif)


Title: I found it somewhat "interesting" that...
Post by: Glenn on February 18, 2003, 02:38:00 AM
errors such as an open drive door wouldn't cause a problem for the INTERRUPT/INTERRUPTX routines if not for a bug in QB.QLB/QB.LIB.  The Redmond Mafia actually (at one time) released new routines (complete with ASM source code) at their website with the bug fixed.  But true to their nature, in fixing the bug they made the routines worse.  The "fixed" routines wouldn't let you use the BP register.  (So I'm still using the old ones.  I need that register.)



Quote:
As I mentioned earlier, some errors can be avoided by using CALL Interrupt to access DOS directly. (One important DOS service lets you see if a file exists before attempting to open it.) But critical errors such as those caused by an open drive door require assembly language. In Chapter 12 you will learn how to bypass BASIC and access DOS directly using CALL Interrupt.