Validating a string - vb.net

I am trying to write a program where the user inputs a telephone number and a message is displayed if it contains a letter.
Module Module1
Sub Main()
Dim TelNumber As String
Dim Character As String
TelNumber = Console.ReadLine()
For Number = 0 To TelNumber.Length - 1
Character = TelNumber.Substring(Number)
If Integer.TryParse(Character, 0) <> 0 Then
Console.WriteLine("It cannot contain a letter")
Exit For
End If
Next
Console.ReadLine()
End Sub
End Module
However with this code even it only works properly if the string contains less than 11 charcaters, after that even if it does not contain any letters it still displays the message. How do I fix this? Also I don't understand what the second parameter of the Integer.TryParse function represents?

TelNumber.Substring(Number) does not just the Numberth character of the string.
It returns the string with Number characters stripped off its beginning.
Thus, in the first step of the loop, TelNumber.Substring(0) returns the whole string.
Then, Integer.TryParse() fails with integer overflow with long string.
Hint: simple string validation is a task for regular expressions.
With regular expressions it will also be very easy to extend tel.number format to something like +4915771828000 or 12-34-56.
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim telNumber As String = Console.ReadLine()
Dim telValidationRegex As Regex = New Regex("^\d+$")
If NOT telValidationRegex.Match(telNumber).Success Then
Console.WriteLine("Wrong telephone number format")
End If
Console.ReadLine()
End Sub
End Module

I don't have a compiler handy, but I can tell you what I think this should look like. First let's look at Int32.TryParse's documentation
result
Type: System.Int32
When this method returns, contains the 32-bit signed integer value equivalent of the number contained in s, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the s parameter is null or String.Empty, is not of the correct format, or represents a number less than MinValue or greater than MaxValue. This parameter is passed uninitialized.
So, the second parameter is supposed to be an integer variable that contains the result of trying to parse the string.
Then, let's look at substring
startIndex
Type: System.Int32
The zero-based starting character position of a substring in this instance.
So what you're doing isn't looking at each character and trying to convert it to an integer. It's looking at the whole number, and trying to convert that to an integer. Then the whole number, except for the first character, and trying to convert that to a number. And so on.
I suspect you'll find that Int32 can only store numbers about 10 digits long (2^32, or 4294967296)
What you want to do is look at each character, something like this.
Module Module1
//Warning, did not try to compile
Sub Main()
Dim TelNumber As String
Dim Character As String
TelNumber = Console.ReadLine()
For Number = 0 To TelNumber.Length - 1
Character = TelNumbert(Number)
Dim OutputNumber as Integer
If Not Integer.TryParse(Character, OutputNumber) Then
Console.WriteLine("It cannot contain a letter")
Exit For
End If
Next
Console.ReadLine()
End Sub
End Module

Related

Equivalent of function String$() VB.Net?

I am migrating an application from VB6 to VB.Net, Which is using the String$() function.
My question is: Which is the "equivalent" of VB6 String$() in following Code?
Dim Symbol As String=""
Dim iRet As Long
iRet = GetLocaleInfo(LCID, LOCALE_SCURRENCY, lpLCDataVar, 0)
Symbol = String$(iRet, 0)
Note that String$() is the function which returns a repeating character string of the length specified:
Syntax:
String$(number, character)
number Length of the returned string.
character Required. Character
code specifying the character or string expression whose first
character is used to build the return string.
(reference)
If I will remove $, It will give me error that "String" is a Class and cannot used as an expression.
This String constructor is the correct way to create a String containing a specific number of a specific character, e.g.
Dim c = "0"c
Dim count = 10
Dim str As New String(c, count)
The equivalent to String$ (in older BASICs) is StrDup (VB.NET).
So, in your case:
Symbol = StrDup(iRet, Chr(0))
The code appears to be getting the currency symbol (and decimal separator) for a culture. It would be better to write it using .NET methods instead of the half-way route of using VB6 in .NET.
For example,
Imports System.Globalization
Module Module1
Sub Main()
Dim lcid = 2057
Dim ci As New CultureInfo(lcid)
Console.WriteLine(ci.EnglishName)
Console.WriteLine(ci.NumberFormat.CurrencySymbol)
Console.WriteLine(ci.NumberFormat.NumberDecimalSeparator)
Console.ReadLine()
End Sub
End Module
outputs
English (United Kingdom)
£
.
There is much more information in the documentation for the CultureInfo Class.

Check string in an array

I have strings stored in an array and need to check if the 5th character of each string is a number or not. The code I used is:
If Mid(arr(i), 5, 1) = IsNumeric(True) Then
MsgBox("Number")
End If
It is giving an error:
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Boolean' is not valid.
You originally tagged your question as vba, but VBA doesn't throw System.InvalidCastException, or any other exception for that matter; vb.net does.
IsNumeric(True) returns True if True is numeric. You want to verify if the string retrieved from the array is numeric; give it the string retrieved from the array as a parameter:
If IsNumeric(Mid(arr(i), 4, 1)) Then
MsgBox("Number")
End If
Your code reads like VB6/VBA though, because of this:
Imports Microsoft.VisualBasic
That namespace contains VB6-like things that you don't need to use at all. The beauty of .net is that everything is an object, so assuming the array is an array of String, you can call the actual String instance methods instead of VB6's Mid function.
Dim theFifthCharacter As String = arr(i).Substring(4, 1)
Or, because you're only interested in 1 character, and a String is itself an IEnumerable(Of Char), you can do this:
Dim theFifthCharacter As Char = arr(i)(4)
Notice the off-by-one - in .net indices start at 0, so if you want the 5th item you'll fetch index 4.
Now, if you want to see if it's numeric, you can try to parse it:
Dim digitValue As Integer
If Int32.TryParse(theFifthCharacter, digitValue) Then
'numeric: digitValue contains the numeric value
Else
'non-numeric: digitValue contains an Integer's default value (0)
End If
Lastly, if you want a message box, use WinForms' MessageBox instead of VB6's MsgBox:
Dim digitValue As Integer
If Int32.TryParse(theFifthCharacter, digitValue) Then
'numeric: digitValue contains the numeric value
MessageBox.Show(string.Format("Number: {0}", digitValue))
Else
'non-numeric: digitValue contains an Integer's default value (0)
MessageBox.Show("Not a number")
End If
A more correct way to do this would be:
If Char.IsDigit(arr(i)(4)) Then
Your syntax is incorrect. It should be:
If IsNumeric(Mid(arr(i), 5, 1)) Then

How to check if input comes null/empty

I need to check if an input comes null/empty.
If input <= 100 And input > 0 And Not input = "" Then
subjectsInt.Add(subjects(i), input)
check = True
End If
I know in that code I am checking it as String but I already did Not input = Nothing and Not input = 0 and I am getting an error:
Run-time exception (line -1): Conversion from string "" to type 'Integer' is not valid.
Stack Trace:
[System.FormatException: Input string was not in a correct format.]
[System.InvalidCastException: Conversion from string "" to type 'Integer' is not valid.]
Any suggestions?
EDIT
Here is the code in case you want to take a look: https://dotnetfiddle.net/0QvoAo
Well, I have looked at your code and there are many problems, all caused by the freely approach to Data Types that VB.NET allows when you have Option Strict set to Off. In this context VB.NET allows you to assign the return value of Console.ReadLine to an Integer trying to help you adding an implicit conversion of the input. Of course if the user types ABCD this implicit conversion has no other way to inform you than triggering an Exception. So I really, really recommend you to use Option Strict set to On (MSDN Option Strict)
Now with Option Strict On your code has a lot of errors, I have rewritten your code and then explain in comments the changes.
Option Strict On
Imports System
Imports System.Collections.Generic
Public Module Module1
Public Sub Main()
Console.WriteLine("Hello World")
' I use a List of strings instead of an untyped array list
Dim subjects As New List(Of String)() From
{
"Math",
"English",
"German"
}
Dim subjectsInt As New System.Collections.Generic.Dictionary(Of String, Integer)
Dim i, input As Integer
Dim check As Boolean
For i = 0 To subjects.Count - 1
check = False
Do
Console.WriteLine(subjects(i) & ": ")
' The input is passed to a string
Dim temp = Console.ReadLine()
' Check if this string is really a number
If Int32.TryParse(temp, input) Then
If input <= 100 And input > 0 Then
subjectsInt.Add(subjects(i), input)
check = True
End If
End If
Loop While check = False
Next
For i = 0 To subjects.Count - 1
Console.WriteLine(subjects(i) & ": " & subjectsInt(subjects(i)))
Next
Console.ReadLine()
End Sub
End Module
The error is telling you that the input is an integer, you can't compare an integer with a string which is precisely what's happening.
Even if the string contains only digit, the type system doesn't convert it inferring from the operator.
In your example, input = "" input can never be "". You should change the type of input to a string and then check before converting it to an integer.
This would be a solution:
Dim integerInput As Integer
Dim stringInput = Console.ReadLine()
If Integer.TryParse(stringInput, integerInput) AndAlso integerInput <= 100 And integerInput > 0 Then
To use < > = with an integer you need to convert the string:
If Integer.Parse(input) <= 100 And Integer.Parse(input) > 0 And Not input = "" Then
Integer.Parse will do the job.
Obviously, if your input is a string and it's not guaranteed that it is going to contain just digit you need either to do some check before or use Integer.TryParse.
The closest you can get to a null check with a value type is EqualityComparer(Of Integer).Default.Equals(id, Nothing); unless you start using Nullable, but it would be too late as the code will fail on the input = Console.ReadLine() when you input a non-digit string.

How can I make this VB program recursive?

I need to use recursion in this program for a school project. The program checks if the number inputted is a real number (in this case defined by a number with a decimal with the characters 0-9 (e.g. 56.7). How would I make the function recursive?
Thanks :-)
Module Real_Numbers
Sub Main()
Dim number As String
Dim check As Boolean
Console.WriteLine("Enter a number to check if it is a real number:")
number = Console.ReadLine()
check = CheckNumber(number)
If check = True Then
Console.WriteLine("The number is a real number")
Else
Console.WriteLine("The number is not a real number")
End If
Console.ReadLine()
End Sub
Function CheckNumber(ByVal number As String) As Boolean
Dim current As Char
For i As Integer = 0 To number.Length - 1
current = number.Substring(i, 1)
If current = "." Then
' Do nothing
Else
If IsNumeric(current) Then
' Do nothing
Else
Return False
End If
End If
Next
Return True
End Function
End Module
Given that this is a homework assignment, I'm not going to write the code out for you. But I will say this -- there are a couple of ways to set this up. One straightforward way would be to pass the string (of the number) to CheckNumber and then check the first character -- if it's numeric, call CheckNumber again with the remainder of the string (everything minus what you just checked). If it's not numeric, return false. You'll need a special case to handle the very last character -- if it's numeric, then return true. If you propagate the boolean response properly, your recursion should unwind itself at the end with the right answer.
Good luck!
You should call the CheckNumber function from within itself, that is a recursion. Learn more about recursion here.

get string after and before word

i need to get a set of values after certain 14 length of a string and before the last 5 stringss.
eg:
Theboyisgoingt9123holdi: so i need to get the value 9123
iamfullofmeats89holdi: i need to extract value 89
so the algorithm here is, i am trying to extract the values that comes after the 14th length of the string and just before the last 5 characters of the same string.
its always whats between 14th and last 5 characters.
i am coding in vb.net.
any ideas is great appreciated.
Dim ResultString As String
ResultString = Regex.Match(SubjectString, "(?<=^.{14}).*(?=.{5}$)").Value
will give you the characters from the 15th until the 6th-to-last character in the string. It is assumed that there are no newlines in the string. If there are, and you want to treat them just like any other character, use the option RegexOptions.Singleline as an additional parameter to Regex.Match().
Explanation:
(?<=^.{14}): Match a position that is after the 14th character in the string.
.*: Match anything until...
(?=.{5}$): ...the position before the last 5 characters in the string.
I too would go with a regex. This is how I would do it:
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim str As String = "Theboyisgoingt9123holdi"
Dim m As Match = Regex.Match(str, "^.{14}(.+).{5}$")
If m.Success Then
Console.WriteLine(m.Groups(1).Value)
End If
End Sub
End Module
This is a great place to use a regular expression
Function GetNumber(ByVal str As String) As String
Dim match = Regex.Match("\d+", str)
if math.Sucess then
Return match.Value
Else
Return String.Empty
End If
End Function