Use Of .length in Substring (VB.NET) - vb.net

Can't figure out why this won't work.
I am trying to analyse a string of variable length containing a "." somewhere inside, and then strip off the "." and all characters before it. This is called via a web service.
When debugging, it works fine until it bails out at the last line, below, with the browser message:
"System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
"
Anyone got any idea?
Code1, below, is an input variable passed to the web service from an eform.
Dim CharNo As New Integer
CharNo = Code1.IndexOf(".")
MyCodebookValueStrip.o_Code1 = Code1.Substring(CharNo + 1, (Code1.Length - CharNo))

Your calculation of the lenth of the remaining string is incorrect. You have to subtract one more:
Code1.Substring(CharNo + 1, Code1.Length - CharNo - 1)
You can also just omit the second parameter, and it will get the rest of the string:
Code1.Substring(CharNo + 1)

Perhaps you could try an alternative and very simple approach?
MyCodebookValueStrip.o_Code1 = Code1.Split(".").Last()
if you're absolutely sure the string does contain a period. Otherwise, use:
MyCodebookValueStrip.o_Code1 = Code1.Split(".").LastOrDefault()
which will return you 'Nothing' if you're string doesn't contain a period.
If your string contains more than one period, you'll get the substring after the last period in the string back. But you do have scope to do otherwise, e.g.:
"StringOne.StringTwo.StringThree".Split(".").First()
will give you "StringOne".
"StringOne.StringTwo.StringThree".Split(".").Last()
will give you "StringThree".
"StringOne.StringTwo.StringThree".Split(".").Skip(1).Take(1)
will give you "StringTwo".
You'll need to reference and import System.Linq to use this stuff, which means you'll need to be using .NET 3.5 or above.

Shouldn't it be:
Code1.Substring(CharNo + 1, (Code1.Length - CharNo - 1))
Because Code1.Length - CharNo gives you an extra character.
Ex:
"abc.abcd"
You want the last 4 characters, and length - charNo will result in 5. Therefore the error.

Dim output As String
Dim Code1 As String = "test.txt"
Dim charNo As Integer = Code1.IndexOf('.')
If ((charNo <> -1) And (Code1.Length <> charNo + 1)) Then
output = Code1.Substring(charNo, Code1.Length - charNo)
Else
output = ""
End If
The above works for me flawlessly.. could it be that you're getting a -1 position from the IndexOf method?

The problem is that you are adding one to the starting index (CharNo + 1), but you don't minus one from the length. To correct it, you should have written:
Code1.Substring(CharNo + 1, (Code1.Length - CharNo - 1))
However, it's unnecessary because all you really needed to do was:
Code1.Substring(CharNo + 1)
Also, you should probably be checking if CharNo + 1 is less than the length, just in case the period was the last character in the text:
If CharNo + 1 < Code1.Length Then
MyCodebookValueStrip.o_Code1 = Code1.Substring(CharNo + 1)
Else
MyCodebookValueStrip.o_Code1 = ""
End If
However, if what you are trying to get is the extension from a file name, you should be using the Path class to do it right (and easier):
MyCodebookValueStrip.o_Code1 = Path.GetExtension(Code1)

Thanks everyone. I should have realised that it needed a -1.
So many right answers here, I'm not sure if I can select more than one as the "accepted answer". I'll give it a try.
Thanks a lot.

Related

Get the nth character, string, or number after delimiter in Visual Basic

In VB.net (Visual Studio 2015) how can I get the nth string (or number) in a comma-separated list?Say I have a comma-separated list of numbers like so:13,1,6,7,2,12,9,3,5,11,4,8,10How can I get, say, the 5th value in this string, in this case 12?I've looked at the Split function, but it converts a string into an array. I guess I could do that and then get the 5th element of that array, but that seems like a lot to go through just to get the 5th element. Is there a more direct way to do this, or am I pretty much limited to the Split function?
In case you are looking for an alternative method, which is more basic, you can try this:
Module Module1
Sub Main()
Dim a As String = "13,1,6,7,2,12,9,3,5,11,4,8,10"
Dim counter As Integer = 5 'the number you want (in this case, 5th one)
Dim movingcounter As Integer = 0 'how many times we have moved
Dim startofnumber, endofnumber, i As Integer
Dim numberthatIwant As String
Do Until movingcounter = counter
startofnumber = InStr(i + 1, a, ",")
i = startofnumber
movingcounter = movingcounter + 1
Loop
endofnumber = InStr(startofnumber + 1, a, ",")
numberthatIwant = (Mid(a, startofnumber + 1, endofnumber - startofnumber - 1))
Console.WriteLine("The number that I want: " + numberthatIwant)
Console.ReadLine()
End Sub
End Module
Edit: You can make this into a procedure or function if you wish to use it in a larger program, but this code run in console mode will give the output of 12.
The solution provided by Plutonix as a comment to my question is straightforward and exactly what I was looking for, to wit:result = csv.Split(","c)(5)In my case I was incrementing a variable each time my program ran and needed to get the nth character or string after the incremented value. That is, if my program had incremented the variable 5 times, then I needed the string after the 4th comma, which of course, is the 5th string. So my solution was something like this:result = WholeString.Split(","c)(IncrementedVariable)Note that this is a zero-based variable.Thanks, Plutonix.

vb.net increment string with prefix

I'm sure this question has been asked before, but I can't find exactly what I'm after.
I have a string which has a string, then a dash, then a number, e.g. "TERM-01" which happens to be the name of an electrical terminal in a switchboard.
I want to increment it to "TERM-02", "TERM-03" etc.
I have come up with this:
TermNo = CStr(Mid(TermNo, 1, InStr(TermNo, "-")) & (CInt(Mid(TermNo, InStr(TermNo, "-") + 1, TermNo.Length - InStr(TermNo, "-")) + 1)))
Which seems to work fairly well, however I need to increment the number including the 0, so 08, 09, 10 instead of 8,9,10.
Any ideas?
You could use the standard Substring method to point to the part where the number starts, convert it to an integer and add your increment. The trick to return the number with the 0 prefix is done using the format specifier D2
Dim TermNo = "TERM-01"
for i = 1 To 15
Dim value = "TERM-" + (Convert.ToInt32( _
TermNo.SubString( _
TermNo.IndexOf("-"))) + i) _
.ToString("D2")
Console.WriteLine(value)
Next
This could also be written using a Regex expression in a more readable way
Dim TermNo = "TERM-01"
for i = 1 To 15
Console.WriteLine(Regex.Replace(TermNo, "\d+", i.ToString("D2")))
Next
If you always have a dash, simply split the string on the dash and deal with the pieces individually.
https://msdn.microsoft.com/en-us/library/system.string.split%28v=vs.110%29.aspx

Checking an array of booleans in VB.NET

I need to check an array of booleans and for each value act accordingly.
Current code is something like this, but i want to make it read easier
If heater_check(0) = true Then
get_temp(0)
End If
If heater_check(1) = true Then
get_temp(1)
End If
...
And so on. Is there a better solution?
I guess this is what you are looking for
For i As Integer = 0 To heater_check.length - 1
If heater_check(i) then
get_temp(i)
End If
Next
"For a case like this, could a For loop still work? If node_num = "1" Then Temperature(0) = C_D(Convert.ToChar(raw_result(byte_num + 22))) + C_D(Convert.ToChar(raw_result(b........ "chia kang ren
And the answer :
"As long as there is a 'pattern' on your variable changes, you can always use loop to simplify your If-Else statement"TheQuickBrownFox
..or use some logic to tie together two variables of different types having some sort of relation between, whenever required.
' ...
Dim TempIndex As Int32 = Integer.Parse(node_num) - 1
' Converts node_num to an Integer and substract 1.
Temperature(TempIndex) = _
C_D(Convert.ToChar(raw_result(byte_num + 22))) + _
C_D(Convert.ToChar(raw_result(byte_num + 21))) * 16 + _
C_D(Convert.ToChar(raw_result(byte_num + 20))) * 256
' ...
By the way, if you're asking A, only answers to A are relevant, or answers that covers A and anything directly related to A like A', -A, A² or |A|.
Here I'm talking about converting a String to Integer. That has nothing to do with :
"I need to check an array of booleans and for each value act accordingly."
=> Please mark TheQuickBrownFox's answer as the valid answer. (And avoid asking other questions than the original one - :) )

Getting the character at an index Visual Basic

I'm trying to get the character at a specified point in a string and I am proficient in Java but am learning VB for a competition tomorrow. I am trying to get the n char in a string..
for example, I have string "12345" and I want the middle character from the string which is '3' in this case. currently I'm trying to use
middle = Nums.Chars(CInt((Nums.Length / 2))+1)
where middle is a String. It gives me a character but sometimes that character isn't even the middle character in the string. The value of middle is the middle number + 1 so I assumed it was the character code of the char ( 0 = 1, 1 = 2, 2 = 3, etc..) but that was just my theory. So I tried to change it to a String by using
middle = Nums.Chars(CInt((Nums.Length / 2))+1) & ""
Alas that still didn't work so now I come here. All criticism is greatly appreciated.
TL;DR I need to find the middle character in a String, in my case the string is always an integer converted to a string.
Try this:
Public Function GetMiddleString(original As String) As String
If original.Length Mod 2 <> 0 AndAlso original.Length >= 3 Then
Return original.Substring(original.Length \ 2 + 1, 1)
Else If orginal.Length Mod 2 = 0 AndAlso original.Length >= 3 Then
Return original.Substring(original.Length \ 2, 1)
End If
Return original
End Function
Note: This assumes that original is not null (Not Nothing).
As far as I know there is Mid() function to get the middle or the index of the middle char.

Replacing nth occurrence of string

This should be fairly simple but I'm having one of those days. Can anyone advise me as to how to replace the first and third occurrence of a character within a string? I have looked at replace but that cannot work as the string could be of different lengths. All I want to do is replace the first and third occurrence.
There is an overload of the IndexOf method which takes a start position as a parameter. Using a loop you'll be able to find the position of the first and third occurences. Then you could use a combination of the Remove and Insert methods to do the replacements.
You could also use a StringBuilder to do the replacements. The StringBuilder has a Replace method for which you can specify a start index and a number of characters affected.
aspiringCoder,
Perhaps something like this might be useful to you (in line with what Meta-Knight was talking about <+1>)
Dim str As String = "this is a test this is a test this is a test"
Dim first As Integer
Dim third As Integer
Dim base As Integer = 0
Dim i As Integer
While str.length > 0
If i = 0 Then
first = str.IndexOf("test")
else if i = 2 Then
third = base + str.IndexOf("test")
end if
base = base + str.IndexOf("test")
str = str.Remove(0, str.IndexOf("test") + "test".length -1 )
i++
End While
It might have a one-off error somewhere...but this should at least get you started.