AboutAlex Barry Expertise I have been a qbasic programmer since 2000, creating games, minor libraries and various small programs. I have experience using interrupts, graphics, file input/output, the mouse cursor, and using libraries. I have also learned FreeBASIC, c/c++, python, php and html.
I do not claim to be an absolute authority in any language, but I don't mind looking things up and learning with you.
Experience Hobby programming since 2000
I no longer belong to any community programming groups, but do have knowledge of *basic dialects and C/C++
Question Hello, I've been trying to create an Email program that allows a user to sign up, and also view their information by signing in. The problem I've been having is that I can't seem to figure out how to make it so that two different people can't sign up with the same username, and also how to make it so that when you sign in, you only view your information, and not the information of others.
If you could help me, I would appreciate it, and here is everything I've worked on for the past few days.
CLS
GOSUB process.request
GOSUB wrapup
END
process.request:
GOSUB display.menu
GOSUB accept.code
DO WHILE code$ <> "3"
SELECT CASE code$
CASE IS = "1"
GOSUB input.data
CASE IS = "2"
GOSUB show.records
END SELECT
GOSUB display.menu
GOSUB accept.code
LOOP
RETURN
accept.code:
COLOR 14
LOCATE 11, 25: INPUT "Make a selection ", code$
COLOR 7
DO WHILE code$ <> "1" AND code$ <> "2" AND code$ <> "3"
BEEP: BEEP
COLOR 12
LOCATE 12, 25: PRINT "Invalid selection"
COLOR 14
LOCATE 11, 46: PRINT " "
LOCATE 11, 42: INPUT " ", code$
COLOR 7
LOOP
CLS
RETURN
input.data:
CLS
PRINT " Welcome to Yahoo Mail"
PRINT " *********************"
PRINT
OPEN "Secret.dat" FOR APPEND AS #1
DO
INPUT "What is your Last Name =========>", lastname$
INPUT "What is your First Name ========>", firstname$
INPUT "What will be your username======>", username$
INPUT "What will be your password =====>", password$
WRITE #1, lastname$, firstname$, username$, password$
PRINT
INPUT "Continue (y or n)?", yn$
LOOP WHILE UCASE$(yn$) = "Y"
CLOSE #1
RETURN
show.records:
CLS
OPEN "Secret.dat" FOR INPUT AS #1
PRINT "Sign in"
PRINT "======="
INPUT "What is your username"; username$
INPUT "What is your password"; password$
'DO WHILE NOT EOF(1)
INPUT #1, lastname$, firstname$, username$, password$
PRINT USING p1$; lastname$; firstname$; username$; password$
'LOOP
SLEEP
CLOSE #1
RETURN
wrapup:
LOCATE 5, 30: PRINT "Have a nice day"
RETURN
Answer Hi, Sovann,
To do this sort of program, you'll need to do a lot of work on your code. First, I'm going to give you a quick introduction to User Defined Types (UDTs), so my code makes sense.
A UDT is a variable type with customized information. So, instead of INTEGER, STRING, or other data types, a UDT have have multiple data for one variable:
TYPE MyFirstUDT
hello AS INTEGER
world AS STRING * 25
END TYPE
If we were to make that a variable:
DIM myUDTvariable AS MyFirstUDT
And to assign values:
myUDTvariable.hello = 5
myUDTvariable.world = "Wow, this is a UDT!"
You'll notice that when I made a string, I put a "* 25" after it. Strings in UDTs need to have a definitive length so QBasic knows how big the variable is in bytes. You can make the string size any positive integer value, but it is necessary.
Here is how I would set your program up:
TYPE UserAccount
' You could add first and last name in here if you desired
' As far as how big the string is for that, it doesn't matter
' I usually stick with powers of 2, but that's just my weird preference
username as string * 64
domain as string * 32
password as string * 128
END TYPE
DECLARE SUB Resize( array() AS UserAccount, size AS INTEGER )
DECLARE FUNCTION LoadInformation%( file AS STRING )
DECLARE SUB UpdateInformation( file AS STRING )
DECLARE FUNCTION NumAccounts%()
DECLARE FUNCTION FindAccount%( username AS STRING )
DECLARE FUNCTION NewAccount%( username AS STRING, password AS STRING )
DIM SHARED domain AS STRING
REDIM SHARED account(0) AS UserAccount
' This can be changed to whatever you want...this would be after the @ symbol
domain = "yahoo.com"
SUB Resize( array() AS UserAccount, size AS INTEGER )
DIM tmp( LBOUND( array ) TO UBOUND( array ) ) AS UserAccount
DIM i AS INTEGER
FOR i = LBOUND( array ) TO UBOUND( array )
tmp( i ) = array( i )
NEXT i
IF size = 0 THEN
REDIM array( 0 ) AS UserAccount
EXIT SUB
END iF
REDIM array( 1 TO size ) AS UserAccount
FOR i = 1 TO size
array( i ) = tmp( i )
NEXT i
END SUB
FUNCTION LoadInformation%( file AS STRING )
LoadInformation% = 0
DIM handle AS INTEGER
DIM size AS INTEGER
DIM num AS INTEGER
DIM tmp AS UserAccount
DIM i AS INTEGER
size = LEN( tmp )
handle = FREEFILE()
OPEN file FOR RANDOM AS #handle LEN=size
num = LOF( handle ) / size
IF num = 0 THEN GOTO loadfinish
REDIM account( 1 TO num ) AS
i = 1
DO UNTIL EOF( handle )
GET #handle, , account( i )
i = i + 1
LOOP
LoadInformation% = 1
loadfinish:
CLOSE #handle
END FUNCTION
SUB UpdateInformation( file AS STRING )
IF NumAccounts%() = 0 THEN EXIT FUNCTION
DIM handle AS INTEGER
DIM size AS INTEGER
DIM tmp AS UserAccount
DIM i AS INTEGER
size = LEN( tmp )
handle = FREEFILE()
KILL file
OPEN file FOR RANDOM AS #handle LEN=size
FOR i = LBOUND( account ) TO UBOUND( account )
PUT #handle, , account( i )
i = i + 1
NEXT i
CLOSE #handle
END SUB
FUNCTION NumAccounts%()
NumAccounts% = UBOUND( account )
END FUNCTION
FUNCTION FindAccount%( username AS STRING )
FindAccount% = 0
IF NumAccounts%() = 0 THEN EXIT FUNCTION
DIM i AS INTEGER
FOR i = LBOUND( account ) to UBOUND( account )
IF username = LTRIM$( RTRIM$( account( i ).username ) ) ) THEN
FindAccount% = i
Exit Function
END IF
NEXT i
END FUNCTION
FUNCTION NewAccount%( username AS STRING, password AS STRING )
NewAccount% = 0
IF FindAccount%( username ) <> 0 THEN EXIT FUNCTION
Resize( account(), NumAccounts%() + 1 )
NewAccount% = UBOUND( accounts )
account( NewAccount% ).username = username
account( NewAccount% ).password = password
account( NewAccount% ).domain = domain
END FUNCTION
All my functions in this code, if they return 0, then an error of some sort has occured (if the file doesn't have account information, if a username is already in use, etc.)
This is how I would setup a user-account system in QBasic. I suggest redoing your code to be procedure oriented (SUB/FUNCTIONs instead of GOTO and GOSUBs). The NewAccount() function creates a new account, and if the username already exists, then it returns 0.
I hope that points you in the right direction,
-Alex