Why is Visual Basics Console.ReadLine Buggy and can I fix it? - vb.net

Hey question about a visual basics program, I am using Console.ReadLine into a string but it seems when I get to that part of the program or any part of my console program the keyboard enter key enters twice or something it completly skips a ReadLine and recieves the input.length 0 before I even have a chance to enter a string.
This isnt runable without my full code I dont think but I cant seem to get ReadLine to prompt for a string when it is initially run, it always returns 0 once and then loops normally. Im wondering if that has something to do with my keyboard or keyboard settings for a visual basics program or command line.
I dont think its a keyboard error because when I am entering code into visual basics it works fine and doesnt send two returns. I couldnt get the full code in code blocks.
...
Shared Sub Main()
Dim s As New Space()
Dim Ship As New Ships()
Dim Run As Boolean = True
Dim ChooseName As Boolean = True
Dim ch As Char
Dim PlayerName As String
While Run = True
s.PrintWelcome()
ch = Convert.ToChar(Console.Read())
If ch = "1" Then
While ChooseName = True
Console.WriteLine("Choose a Name Less then 50 Characters: ")
PlayerName = Console.ReadLine()
If PlayerName.Length > 50 Then
Console.WriteLine("Name is to Long!")
ElseIf PlayerName = "Q" Then
Run = False
Exit While
ElseIf PlayerName.Length <= 0 Then
Console.WriteLine("Please Enter a Player name or Q by itself to quit.")
Else
ChooseName = False
Console.WriteLine("PlayerName: " & PlayerName & " PlayerName.Length: {0}", PlayerName.Length)
End If
End While
If Run = True Then
End If
ElseIf ch = "2" Then
ElseIf ch = "3" Then
Run = False
ElseIf ch = "Q" Then
Run = False
Else
s.PrintWelcome()
End If
End While
End Sub
...

I suspect that you really ought to be structuring your code more like this:
Module Module1
Sub Main()
Do
Console.Write("Please select a menu item from 1, 2, 3 or Q to quit: ")
Dim menuSelection = Console.ReadKey()
Dim input As String = Nothing
Console.WriteLine()
Select Case menuSelection.KeyChar
Case "1"c
Console.WriteLine("What did you want to say about 1?")
input = Console.ReadLine()
Case "2"c
Console.WriteLine("What did you want to say about 2?")
input = Console.ReadLine()
Case "3"c
Console.WriteLine("What did you want to say about 3?")
input = Console.ReadLine()
Case "q"c, "Q"c
Exit Do
Case Else
'Do nothing before repeating the prompt.
End Select
If Not String.IsNullOrEmpty(input) Then
Console.WriteLine("You said: " & input)
End If
Loop
End Sub
End Module
The ReadKey call will immediately read the first key entered by the user. Rather than requiring the user to hit Enter after that key, the application writes the line break itself. It then tests the chararacter represented by that key to see if it is a valid menu item. If it is, it does whatever is appropriate for that item, whether that be reading a line of input or quitting. If the key does not represent a valid menu item then it simply loops back to the prompt. Note also that the Char value entered by the user is actually compared to Char literals, the way it should be done, rather than String literals.

Related

Storing string then displaying it with a label box

I am trying to store the string from an input box and then display it with dashes in the lblbox for a hangman game for a class.
These are the tasks that I am struggling with:
edit the program to allow a Secret Word of any length.
the program will allow the ‘guesser’ to guess 2 times the length of the word. As an example, the word ‘code’ will allow 8 total guesses.
As the user guesses at letters contained in the word the program will:
Count the number of attempts the user has completed.
Replace the appropriate dash (-) with the correct letter, if the correct letter has been guessed.
When all the letters have been guessed correctly all the dashes (-) should be replaced with the appropriate letters, and a message box should appear stating “Great Job playing Hangman.!”
If the user is unable to guess the correct word in the amount of guesses allowed; the dashes (-) should be replaced with GAME OVER! and a message box should appear stating “Sorry the correct word was________”
2 bonus points will be awarded for displaying all incorrect letters guess in a 3rd label control.
4 more additional bonus points will be awarded for not allowing, or counting a user who guesses the same incorrect letter twice.
Here is my code:
Dim strSecretWord As String
Dim strLetterGuessed As String
Dim blnDashReplaced As Boolean
Dim intNumberOfRemainingGuesses As Integer = 10
Dim intNumofGuesses As Integer = 0
lblSecretWord.Text = ""
lblNumberOfAttempts.Text = ""
'start game and have 1st user input a 5 letter word that 2nd player needs to guess
strSecretWord = InputBox("Please input a 5 letter word for user to guess:", "Please input secret word.").ToUpper
'displays five dashes for the secret word
lblSecretWord.Text = lblSecretWord.Text & "-----"
'guessing player recieves inputbox to make letter guesses
MessageBox.Show("The length of the word is 5 letters, you will be given 10 guesses", "10 guesses", MessageBoxButtons.OK)
MessageBox.Show("Player who gets to guess, BE READY!", "Good Luck Guessing", MessageBoxButtons.OK)
'Counts number of attempts player gets (10) and replaces dashes with guessed letter if correct
'If guessed letter was incorrect, user loses a turn
For intNumberofGuesses = 1 To 10
strLetterGuessed = InputBox("Please guess a letter:", "Letter Guess").ToUpper
'Uses an IntIndex counter of 0 to 4 to execute 5 times (5 dashes)
'Also uses the value of intIndex to check each of the 5 locations of the strSecretWord
For intIndex As Integer = 0 To 4
'if the user has guessed a correct letter then remove a dash and insert the correct letter guessed
If strSecretWord.Substring(intIndex, 1) = strLetterGuessed Then
lblSecretWord.Text = lblSecretWord.Text.Remove(intIndex, 1)
lblSecretWord.Text = lblSecretWord.Text.Insert(intIndex, strLetterGuessed)
blnDashReplaced = True
End If
Next intIndex
'If the user guessed a correct letter on their last guess the blnDashReplaced is set and the true condition of the If statement is executed
If blnDashReplaced = True Then
'if there are no more dashes, and the game has been solved.
If lblSecretWord.Text.Contains("-") = False Then
MessageBox.Show("Great Job playign Hangman!", "Game Over", MessageBoxButtons.OK)
lblRemainingNumberOfAttempts.Text = ""
lblNumberOfAttempts.Text = ""
Exit Sub
Else
blnDashReplaced = False
End If
Else
End If
lblNumberOfAttempts.Text = intNumberofGuesses
intNumberOfRemainingGuesses = intNumberOfRemainingGuesses - 1
lblRemainingNumberOfAttempts.Text = intNumberOfRemainingGuesses
Next
lblSecretWord.Text = "GAME OVER!"
MessageBox.Show("Better luck next time. Sorry the correct word was " & strSecretWord & ".", "You Lost", MessageBoxButtons.OK)
lblRemainingNumberOfAttempts.Text = ""
lblNumberOfAttempts.Text = ""
I added a list box to keep the guessed letters. Other comments and explanations in line.
Public Class Form3
'Move this to a class level variable so it can be seen by
'all the methods in the class
Private strSecretWord As String
Private Sub btnStartGame_Click(sender As Object, e As EventArgs) Handles btnStartGame.Click
Dim strLetterGuessed As String
Dim blnDashReplaced As Boolean
Dim intNumberOfRemainingGuesses As Integer
Dim intNumofGuesses As Integer = 0
'Display correct number of dashes
Dim numberOfDashes As Integer = strSecretWord.Length
'Create a string with correct number of dashes
'This uses and overload of the String constructor that takes a Char and an integer
'as arguments and returns a string with that character repeated that number
'of times. The lower case c following "-" indicates that - is a Char.
Dim TotalNumofGuesses = numberOfDashes * 2
lblRemainingNumberOfAttempts.Text = TotalNumofGuesses.ToString
intNumberOfRemainingGuesses = TotalNumofGuesses
Dim dashString As String = New String("-"c, numberOfDashes)
'displays the dashes
lblSecretWord.Text = dashString
'guessing player recieves inputbox to make letter guesses
'You can use an Interpolated string to display variables in line surrounded by { }.
'In older versions of VB String.Format() will yield the same result.
MessageBox.Show($"The length of the word is {numberOfDashes} letters, you will be given {TotalNumofGuesses} guesses", $"{TotalNumofGuesses} guesses", MessageBoxButtons.OK)
MessageBox.Show("Player who gets to guess, BE READY!", "Good Luck Guessing", MessageBoxButtons.OK)
'Counts number of attempts player gets and replaces dashes with guessed letter if correct
'If guessed letter was incorrect, user loses a turn
For counter = 1 To TotalNumofGuesses
strLetterGuessed = InputBox("Please guess a letter:", "Letter Guess").ToUpper
'If lstLettersGuessed.Contains(strLetterGuessed) Then
If lbxLettersGuessed.Items.Contains(strLetterGuessed) Then
MessageBox.Show($"{strLetterGuessed} has already been guessed.", "Try Again")
'need to do this so they are not cheated out of a guess
TotalNumofGuesses += 1
Continue For 'Moves to the next iteration of the For
End If
lbxLettersGuessed.Items.Add(strLetterGuessed)
'lstLettersGuessed.Add(strLetterGuessed)
'Uses an IntIndex counter of 0 to 4 to execute 5 times (5 dashes)
'Also uses the value of intIndex to check each of the 5 locations of the strSecretWord
For intIndex As Integer = 0 To numberOfDashes - 1
'if the user has guessed a correct letter then remove a dash and insert the correct letter guessed
If strSecretWord.Substring(intIndex, 1) = strLetterGuessed Then
lblSecretWord.Text = lblSecretWord.Text.Remove(intIndex, 1)
lblSecretWord.Text = lblSecretWord.Text.Insert(intIndex, strLetterGuessed)
blnDashReplaced = True
End If
Next intIndex
'If the user guessed a correct letter on their last guess the blnDashReplaced is set and the true condition of the If statement is executed
If blnDashReplaced = True Then
'if there are no more dashes, and the game has been solved.
If lblSecretWord.Text.Contains("-") = False Then
MessageBox.Show("Great Job playing Hangman!", "Game Over", MessageBoxButtons.OK)
'Do this at start of game, player wants to see final score
'lblRemainingNumberOfAttempts.Text = ""
'lblNumberOfAttempts.Text = ""
Exit Sub
Else
blnDashReplaced = False
End If
End If
'This is a shorter way of incrementing a variable
intNumofGuesses += 1
'Can't put an integer into a Text property, it needs a string
lblNumberOfAttempts.Text = intNumofGuesses.ToString
'This is a shorter way of decrementing a variable
intNumberOfRemainingGuesses -= 1
'Can't put an integer into a Text property, it needs a string
lblRemainingNumberOfAttempts.Text = intNumberOfRemainingGuesses.ToString
Next
lblSecretWord.Text = "GAME OVER!"
MessageBox.Show("Better luck next time. Sorry the correct word was " & strSecretWord & ".", "You Lost", MessageBoxButtons.OK)
'Do this at start of game
'lblRemainingNumberOfAttempts.Text = ""
'lblNumberOfAttempts.Text = ""
End Sub
Private Sub btnSetUp_Click(sender As Object, e As EventArgs) Handles btnSetUp.Click
lblSecretWord.Text = ""
lblNumberOfAttempts.Text = "0"
lblRemainingNumberOfAttempts.Text = "0"
lbxLettersGuessed.Items.Clear()
'start game and have 1st user input a 5 letter word that 2nd player needs to guess
strSecretWord = InputBox("Please input a word for user to guess:", "Please input secret word.").ToUpper
End Sub
End Class

Is there any shorter way of writing this code?

I am extremely new to programming, currently just messing around with console apps. I've created a few things like a login screen and a currency converter but that was with aid from teachers. Never done anything by myself.
I'm wondering if there's any better/shorter way of writing this?
Module Module1
Sub Main()
Dim x As String
Dim Y As String
Dim yes As String
Dim no As String
x = "Please enter your name:"
Y = "Please enter 'Y' or 'N'"
yes = "Y"
no = "N"
Console.WriteLine(x)
Console.ReadLine()
Console.WriteLine("Do you wish to continue?")
yes = Console.ReadLine()
Console.WriteLine(Y)
If yes = "Y" Then
Console.WriteLine("You selected to continue")
Else
If no = "N" Then
Console.WriteLine("You selected to exit")
Environment.Exit(0)
End If
End If
Console.WriteLine("TEXT HERE") 'Text here as I don't know what to put next yet
Console.ReadLine()
Console.ReadLine() 'Just put this here so it doesn't exit straight away
End Sub
I had declared some variables just to try it out rather than just have Console.WriteLine("TEXT") constantly. I'm just trying to find ways of doing things.
I just ran the code again and saw that it's case sensitive to the user input, how would I go about having it be either Y or y and N or n?
You can use the following code:
Sub Main()
Console.WriteLine("Please enter your name:")
Console.ReadLine()
Console.WriteLine("Do you wish to continue?")
Do
Dim selectYN As String = Console.ReadLine()
If selectYN.ToUpper = "Y" Then
Console.WriteLine("You selected to continue")
Exit Do
ElseIf selectYN.ToUpper = "N" Then
Console.WriteLine("You selected to exit")
Environment.Exit(0)
Exit Do
Else
Console.WriteLine("Please enter 'Y' or 'N'")
End If
Loop
Console.WriteLine("TEXT HERE") 'Text here as I don't know what to put next yet
Console.ReadLine()
Console.ReadLine() 'Just put this here so it doesn't exit straight away
End Sub
The code is much more minified than your code. I added also a loop until the user added a valid answer for the yes/no question. The user have to enter one of the following values to break the loop: n, N, y, Y. If the value is not valid the question appears again to give himn a chance to enter a new value again.
How would I go about having it be either Y or y and N or n?
In this case you have the possibility to convert the letter toLower or toUpper. In the example above toUpper is used to check against N and Y.

For loop for bowling score array

I am trying to create a bowling program that will display the scores given in a multi-line text box. I've manage to get the program giving an output, but when it runs it skips asking for new inputs and just gives 5 0s on seperate lines and nothing else. I'm completely lost, any help is very much appreciated
EDIT: Sorry should have changed errors to reflect the programs changes, it looks like this now. It gives 0's instead of using the value I gave it, but it does ask for each input now.
For gameNumber As Integer = 1 To 5 Step 1
lblEnterScore.Text = "Enter Score for game #" & gameNumber
Dim Testint As Integer ' define an Integer for testing
Try
Testint = CInt(txtScoreInput.Text) ' try to convert whatever they entered to Int
Catch
MessageBox.Show("Entry is not an Integer") ' If you are here then the CInt failed for some reason, send a message
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End Try
If txtScoreInput.Text.Contains(".") Then
MsgBox("Bowling Score must be a whole number.")
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End If
If txtScoreInput.Text > MAXIMUM_SCORE Or txtScoreInput.Text < MINIMUM_SCORE Then
MsgBox("Bowling Score must be between 1 and 300.")
txtScoreInput.SelectAll()
txtScoreInput.Focus()
Exit Sub
End If
scoreInput(gameNumber) = CInt(txtScoreInput.Text)
' and store it in the array
' and increment the gamecounter for the next time through the loop
Next
'btnEnterScore.Enabled = False
' place the good score into the multi-line textbox
txtScoreOutputs.Text = gameScore & vbCrLf & txtScoreOutputs.Text
End Sub
If it was me, here's what I would do... Just a suggestion; I also cut out over half of your code and stopped it from throwing exceptions as well... You can put this in a click event or where ever you need it as well. You can modify this as well to take as many as you want from user input as well not just limit them from entering score's. Your user also has the option to get out of that loop when they choose to do so as well, not keeping them inside the loop...
Private ScoreLists As New List(Of Integer) 'Hold your inputted values
Private Const MAXIMUM_SCORE As Integer = 300 'Max score
Private Const MINIMUM_SCORE As Integer = 1 'Min score
Private blnStop As Boolean = False
Try
For gameNumber As Integer = 1 To 5
Dim intScore As Integer = 0
Do Until (intScore >= MINIMUM_SCORE And intScore <= MAXIMUM_SCORE) OrElse blnStop
If Not Integer.TryParse(InputBox("Please enter a score for game # " & gameNumber.ToString), intScore) Then
If MsgBox("Bowling Score must be a whole number. Stop getting scores?.", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
blnStop = True
Exit For
End If
End If
Loop
ScoreLists.Add(intScore)
Next
'Display the results...
For i As Integer = 0 To ScoreLists.Count - 1
txtScoreOutputs.Text &= ScoreLists.Item(i.ToString)
Next
ScoreLists.Clear()
Catch ex As Exception
End Try
Construct your logic like this (pseudo):
Loop
{
AskUserForInput()
ProcessUserInput()
}
The loop part will control how many scores the user is prompted to enter. The AskUserForInput() function will prompt the user to type in a new score, and the ProcessUserInput() function will get the value and store it in an array or print it to the screen, etc.
Your current logic is not waiting for any new user input before trying to add to the scores. You are also getting zeros because you're setting the txtScoreOutputs with gameScore, which doesn't look like it's been set to the user's input.

Struggling to make nursery rhyme conditions work

I've been making Baa Baa Black Sheep in VB and have gotten stuck on the final bit of my program. Im trying to make the program state whether the user has entered the correct information for the people who own the bags, but it doesn't seem to register the final part. Any help is greatly appreciated!
Module Module1
Sub Main()
Dim WoolAnswer As String = ""
Dim BagNumber As Integer = 0
Dim FirstBag As String = ""
Dim SecondBag As String = ""
Dim ThirdBag As String = ""
Console.WriteLine("Do you have any wool?")
WoolAnswer = Console.ReadLine
If WoolAnswer = "yes" Then
Console.WriteLine("How many bags do you have?")
BagNumber = Console.ReadLine
If BagNumber = 3 Then
Console.WriteLine("Who is the first bag for?")
FirstBag = Console.ReadLine()
Console.WriteLine("Who is the second bag for?")
SecondBag = Console.ReadLine
Console.WriteLine("Who is the third bag for?")
ThirdBag = Console.ReadLine
Else
Console.WriteLine("That is not the correct amount of bags.")
End If
Else
Console.WriteLine("You have no wool.")
End If
**If (FirstBag = "master" & SecondBag = "dame" & ThirdBag = "little girl") Then
Console.WriteLine("You really know your nursery rhymes!")
End If**
**This is the part that doesn't work**
Console.ReadLine()
End Sub
End Module
You should use the AndAlso operators to compare your values.
If FirstBag = "master" AndAlso SecondBag = "dame" AndAlso ThirdBag = "little girl" Then
You could do it with plain And operators, but AndAlso supports short-circuiting.
Edit: Short-circuiting is a programming construct which allows you to skip over evaluation of portions of a multi part conditional statement if an earlier portion of the statement renders checking the rest of the statement pointless.
Example: a == b AndAlso c == d will not attempt to evaluate c == d if a == b returns false

Console Application on VB2008 - Integer.TryParse Method Error

I am using Integer.TryParse Method to validate whether user input is a numeric or non-numeric in my program.
1)if the user input is numeric, the program will then proceed and validate that the user input is range from 0 to 9.
2)If the user is enter a non-numeric input, the program will display the message "invalid input" and ask user to start from beginning.
Following is my coding:
Sub Main()
Dim sevenNumbers As Integer()
sevenNumbers = New Integer(6) {}
Dim index As Integer
Dim number As Integer
Dim reEnter As Boolean = True
Console.WriteLine("Please enter 7 integers: ")
Console.WriteLine("<ATTENTION: FROM 0 TO 9 ONLY>")
Console.WriteLine()
While reEnter
For index = 0 To 6
Console.WriteLine("Please enter the integer no." & "{0}" & " : ", index + 1) 'Prompt user to enter 7 integers.
sevenNumbers(index) = Console.ReadLine() 'The 7 integers are stored in an array.
If Integer.TryParse(sevenNumbers(index), number) Then
While sevenNumbers(index) < 0 Or sevenNumbers(index) > 9
Console.WriteLine("<invalid input>")
Console.WriteLine()
Console.WriteLine("------------------------------------------")
Console.WriteLine("<Please re-enter the 7 integers>")
Console.WriteLine("------------------------------------------")
Console.WriteLine()
reEnter = True
Exit For
End While
Else
Console.WriteLine("<invalid input>")
Console.WriteLine()
Console.WriteLine("------------------------------------------")
Console.WriteLine("<Please re-enter the 7 integers>")
Console.WriteLine("------------------------------------------")
Console.WriteLine()
reEnter = True
Exit For
End If
reEnter = False
Next
End While
End Sub
However, when a user enter a non-numeric input, the program can't continue and shows an error that forced to close.
i tried this
Sub Main()
Dim num As Integer
Console.Write("enter num:")
Dim input = Console.ReadLine
If Integer.TryParse(input, num) Then
Console.WriteLine("valid. num = " & num)
Else
Console.WriteLine("invalid")
End If
End Sub
it does works and i am wondering which part of my coding is wrong??
Thank for help!!
Your two samples of code are different. In your second attempt, you do this:
Dim input = Console.ReadLine
If Integer.TryParse(input, num) Then
The above code reads into a variable called input that will be a String (because Console.ReadLine returns a String). Then, you try to parse the string into a number.
However, in your original code, you do this (some lines omitted for clarity):
Dim sevenNumbers As Integer()
sevenNumbers = New Integer(6) {}
...
sevenNumbers(index) = Console.ReadLine()
In this case, you are reading into a variable that you have explicitly declared to be an Integer. If the user types "abc" then the conversion will fail at this point - you won't even get to the TryParse because you can't complete the innput.
Instead of reading to an integer, you need to read into a String variable and then parse that value into an Integer (as you did in your second code).
You could have spotted this yourself by taking note of the line that the error actually occurs on when debugging: you should note that the program crashes on the ReadLine, not on the TryParse.
Um. This line:
sevenNumbers(index) = Console.ReadLine()
Is storing whatever text has been read into an array of Integers. If it's compiling, then by the time you reach any later code, you're too late to control the conversion. It's already happened.
Maybe sevenNumbers should be String()?
(You really ought to turn on OPTION STRICT and OPTION EXPLICIT - it should find problems like this for you when it compiles the code)