How do I remove blank lines from text File? vb.net? - vb.net

I have a program I am creating and when i go to remove blank lines this is how I go about it.
For Each i As ListViewItem In lvSongs.SelectedItems
lvSongs.Items.Remove(i)
CurrentSong = i.SubItems(4).Text 'This is the Songs Path
files = File.ReadAllText("songs.txt") 'The songs path's are in the txt
'I am using this as a list of lines i want to keep in
'the txt file.
Dim linesToKeep As New List(Of String)
For Each line As String In files 'Goes through lines
If Not line.Contains(CurrentSong) Then 'checks to see if line is Current song
linesToKeep.Add(line) 'Adds line if its not CurrentSong to the list
End If
Next
File.WriteAllLines("songs.txt", linesToKeep.ToArray())
but when i go to check the txt document, i get this:
EXAMPLE (but written horizontally, each letter being on a new line)
in the text file my friend says its because i have lines set as a string instead of a string().
Thanks for anyhelp!
Ask for more information if im confusing you...

The problem is you are using the ReadAllText API. This returns a String not a String() hence when you later iterate you are iterating over every character in the file, not every line. To fix this use the ReadAllLines API which returns a String()
files = File.ReadAllLines("songs.txt")
Note I can't tell if files is an implicitly declared local or a field. If it's a field typed to String you will need to change the type to String().

Related

How can I split names of directories in certain path from its full path (VB.NET)

Hello world!
I've ran into a problem. I am getting directories contained in certain path and I need to separate the path VB.NET's giving me (like this:
"D:\ApplicationFolder\Addons\Pack_1",
"D:\ApplicationFolder\Addons\Pack_2" ...
Only into this:
"Pack_1", "Pack_2"
So far I've tried this, but I can't get into a solution, I am lost...
Dim ADDONPACKS_DIRECTORIES As String() = Directory.GetDirectories(ADDONS_PATH) ' GETTING ALL DIRECTORIES (PATHS) IN THIS PATH
For Each ADDONPACKS_DIRECTORY In ADDONPACKS_DIRECTORIES ' TRYING TO SPLIT FULL PATH OF THESE DIRECTORIES TO GET ONLY THE NAME OF THESE DIRECTORIES
ADDONPACKS_DIRECTORY.Split()
Dim ADDONPACKS_LENGTH As Integer = ADDONPACKS_DIRECTORY.Length()
MsgBox(ADDONPACKS_DIRECTORY(2))
Next
' Here I want to assign names of these directories onto a label. But the fields only show letters instead of the path segments.
Addonpack1.Text = ADDONPACKS_DIRECTORIES(0)
Addonpack2.Text = ADDONPACKS_DIRECTORIES(1)
Addonpack3.Text = ADDONPACKS_DIRECTORIES(2)
Addonpack4.Text = ADDONPACKS_DIRECTORIES(3)
Addonpack5.Text = ADDONPACKS_DIRECTORIES(4)
'Addonpack6.Text = ADDONPACKS_DIRECTORY(5)
Any ideas? I really appreciate further help.
string.Split() is a Function: it returns a value.
Here: ADDONPACKS_DIRECTORY.Split(), you are splitting the string using the default separator (a white space) but the result is not assigned to anything, so it's lost (but it wouldn't be useful anyway).
This: MsgBox(ADDONPACKS_DIRECTORY(2)), will show only one char of the current Directory path. A string is a collection (an array) of chars. You're asking to show the 3rd.
If you think you won't need the complete directory listing anymore, you could Split the initial collection directly:
Dim ADDONPACKS_DIRECTORIES As String() = Directory.GetDirectories(ADDONS_PATH).
Select(Function(d) d.Split("\"c).Last()).ToArray()
Addonpack1.Text = ADDONPACKS_DIRECTORIES(0)
'(...)
If you instead are going to use that collection of Paths later, you could Split each path and assign the result to each TextBox.Text property, leaving the original collection untouched:
Addonpack1.Text = ADDONPACKS_DIRECTORIES(0).Split("\"c).Last()
Addonpack2.Text = ADDONPACKS_DIRECTORIES(1).Split("\"c).Last()
'(...)
Do you know beforehand how many Addons you will have?
If not, a TextBox for each path might not be the right object to use as the output.
Maybe, you could use a single multiline TextBox. It's Lines() property will hold the array of all the Sub-Paths you appended.
Using the first snippet, it could be something like this:
For Each subpath As String In ADDONPACKS_DIRECTORIES
TextBox1.AppendText(subpath & Environment.NewLine)
Next
Note:
As LarsTech noted in the comments, you could use Path.GetFileName() insted of splitting the path using the path separator.
It would work with both file names and path names, because Path.GetFileName returns the substring of a path when it first finds a path separator, parsing the string from the end to the start, no matter if the substring represents a path or a file name.
Addonpack1.Text = Path.GetFileName(ADDONPACKS_DIRECTORIES(0))
'(...)

how to search and display specific line from a text file vb.net

Hi I am trying to search for a line which contains whats the user inputs in a text box and display the whole line. My code below doesnt display a messsagebox after the button has been clicked and i am not sure if the record has been found
Dim filename, sr As String
filename = My.Application.Info.DirectoryPath + "\" + "mul.txt"
Dim file As String()
Dim i As Integer = 0
file = IO.File.ReadAllLines(filename)
Dim found As Boolean
Dim linecontain As Char
sr = txtsr.ToString
For Each line As String In file
If line.Contains(sr) Then
found = True
Exit For
End If
i += 1
If found = True Then
MsgBox(line(i))
End If
Next
End Sub
You should be calling ReadLines here rather than ReadAllLines. The difference is that ReadAllLines reads the entire file contents into an array first, before you can start processing any of it, while ReadLines doesn't read a line until you have processed the previous one. ReadAllLines is good if you want random access to the whole file or you want to process the data multiple times. ReadLines is good if you want to stop processing data when a line satisfies some criterion. If you're looking for a line that contains some text and you have a file with one million lines where the first line matches, ReadAllLines would read all one millions lines whereas ReadLines would only read the first.
So, here's how you display the first line that contains specific text:
For Each line In File.ReadLines(filePath)
If line.Contains(substring) Then
MessageBox.Show(line)
Exit For
End If
Next
With regards to your original code, your use of i makes no sense. You seem to be using i as a line counter but there's no point because you're using a For Each loop so line contains the line. If you already have the line, why would you need to get the line by index? Also, when you try to display the message, you are using i to index line, which means that you're going to get a single character from the line rather than a single line from the array. If the index of the line is greater than the number of characters in the line then that is going to throw an IndexOutOfRangeException, which I'm guessing is what's happening to you.
This is what comes from writing code without knowing what it actually has to do first. If you had written out an algorithm before writing the code, it would have been obvious that the code didn't implement the algorithm. If you have no algorithm though, you have nothing to compare your code to to make sure that it makes sense.

RichTextBox type of output & removing duplicates

I'm trying to make a small VB program to remove duplicate lines and empty lines from plain text.
I have the RichTextBox input but eventually I do not know what the type of the returned object is, is it an array or a list maybe ?
Also I'm trying to find the most efficient way to remove duplicate lines from big plain text(s), in Python I do it this way :
lines_nodupes = {}
for elt in lines :
lines_nodupes[elt] = ""
Since you can not have twice the same key, no duplicates are kept in the lines_nodupes dictionnary and I can enumerate it to access the lines.
There are two properties you can use :
Lines will return an array of Strings
Text will return the entire text as a string
See RichTextBox from MSDN
If you want to do as in Python :
Dim noDup as new Dictionary(Of String, String)
For Each line in MyRichTextBox.Lines
if not noDup.ContainsKey(line) then
noDUp.add(line, "")
End if
Next
You can also do (as suggested by VisualVincent in the coments) :
Dim noDup as new List(Of String)
For Each line in MyRichTextBox.Lines
if not noDup.Contains(line) then
noDUp.add(line)
End if
Next
which is a bit slower but difference won't be seen unless you have a very long list of items.

VB.Net Read multi column text file and load into ListBox

First, I am not a programmer, I mainly just do simple scripts however there are somethings that are just easier to do in VB, I am pretty much self taught so forgive me if this sounds basic or if I can't explain it to well.
I have run into an issue trying to load a multi-column text file into a list box. There are two separate issues.
First issue is to read the text file and only grab the first column to use in the listbox, I am currently using ReadAllLines to copy the text file to a string first.
Dim RDPItems() As String = IO.File.ReadAllLines(MyDocsDir & "\RDPservers.txt")
However I am having a difficult time finding the correct code to only grab the first Column of this string to put in the listbox, if I use the split option I get an error that "Value of type '1-dimensional array of String' cannot be converted to 'String'"
The code looked like
frmRDP.lstRDP.Items.Add() = Split(RDPItems, ";", CompareMethod.Text)
This is the first hurdle, the second issue is what I want to do is if an item is selected from the List box, the value of the second column gets pulled into a variable to use.
This part I'm not even sure where to begin.
Example data of the text file
Server1 ; 10.1.1.1:3389
Server2 ; 192.168.1.1:8080
Server3 ; 172.16.0.1:9833
.....
When it's working the application will read a text file with a list of servers and their IPs and put the servers in a listbox, when you select the server from the listbox it and click a connect button it will then launch
c:\windows\system32\mstsc.exe /v:serverip
Any help would be appreciated, as I can hard code a large list of this into the VB application it would be easier to just have a text file with a list of servers and IPs to load instead.
The best practise for this would probably be to store your "columns" in a Dictionary. Declare this at class level (that is, outside any Sub or Function):
Dim Servers As New Dictionary(Of String, String)
When you load your items you read the file line-by-line, adding the items to the Dictionary and the ListBox at the same time:
Using Reader As New IO.StreamReader(IO.Path.Combine(MyDocsDir, "RDPservers.txt")) 'Open the file.
While Reader.EndOfStream = False 'Loop until the StreamReader has read the whole file.
Dim Line As String = Reader.ReadLine() 'Read a line.
Dim LineParts() As String = Line.Split(New String() {" ; "}, StringSplitOptions.None) 'Split the line into two parts.
Servers.Add(LineParts(0), LineParts(1)) 'Add them to the Dictionary. LineParts(0) is the name, LineParts(1) is the IP-address.
lstRDP.Items.Add(LineParts(0)) 'Add the name to the ListBox.
End While
End Using 'Dispose the StreamReader.
(Note that I used IO.Path.Combine() instead of simply concatenating the strings. I recommend using that instead for joining paths together)
Now, whenever you want to get the IP-address from the selected item you can just do for example:
Dim IP As String = Servers(lstRDP.SelectedItem.ToString())
Hope this helps!
EDIT:
Missed that you wanted to start a process with it... But it's like charliefox2 wrote:
Process.Start("c:\windows\system32\mstsc.exe", "/v:" & Servers(lstRDP.SelectedItem.ToString()))
Edit: #Visual Vincent's answer is way cleaner. I'll leave mine, but I recommend using his solution instead. That said, scroll down a little for how to open the server. He's got that too! Upvote his answer, and mark it as correct!
It looks like you're trying to split an array. Also, ListBox.Items.Add() works a bit differently than the way you've written your code. Let's take a look.
ListBox.Items.Add() requires that you provide it with a string inside the parameters. So you would do it like this:
frmRDP.lstRDP.Items.Add(Split(RDPItems, ";", CompareMethod.Text))
But don't do that!
When you call Split(), you must supply it with a string, not an array. In this case, RDPItems is an array, so we can't split the entire thing at once. This is the source of the error you were getting. Instead, we'll have to do it one item at a time. For this, we can use a For Each loop. See here for more info if you're not familiar with the concept.
A For Each loop will execute a block of code for each item in a collection. Using this, we get:
For Each item In RDPItems
Dim splitline() As String = Split(item, ";") 'splits the item by semicolon, and puts each portion into the array
frmRDP.lstRDP.Items.Add(splitline(0)) 'adds the first item in the array
Next
OK, so that gets us our server list put in our ListBox. But now, we want to open the server that our user has selected. To do that, we'll need an event handler (to know when the user has double clicked something), we'll have to find out which server they selected, and then we'll have to open that server.
We'll start by handling the double click by creating a sub to deal with it:
Private Sub lstRDP_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles lstRDP.MouseDoubleClick
Next, we'll get what the user has selected. Here, we're setting selection equal to the index that the user has selected (in this case, the first item is 0, the second is 1, and so on).
Dim selection As Integer = lstRDP.SelectedIndex
Lastly, we need to open the server. I'm assuming you want to do that in windows explorer, but if I'm mistaken please let me know.
Dim splitline() As String = Split(RDPItems(selection), ";")
Dim location As String = Trim(splitline(1))
We'll need to split the string again, but you'll notice this time I'm choosing the item whose location in the array is the same as the index of the list box the user has selected. Since we added our items to our listbox in the order they were added to our array, the first item in our listbox will be the first in the array, and so on. The location of the server will be the second part of the split function, or splitline(1). I've also included the Trim() function, which will remove any leading or trailing spaces.
Finally, we need to connect to our server. We'll use Process.Start() to launch the process.
Process.Start("c:\windows\system32\mstsc.exe", "/v:" & location)
For future reference, to first argument for Process.Start() is the location of the process, and the second argument is any argument the process might take (in this case, what to connect to).
Our final double click event handler looks something like this:
Private Sub lstRDP_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles lstRDP.MouseDoubleClick
Dim selection As Integer = lstRDP.SelectedIndex
Dim splitline() As String = Split(RDPItems(selection), ";")
Dim location As String = Trim(splitline(1))
Process.Start("c:\windows\system32\mstsc.exe", "/v:" & location)
End Sub
A final note: You may need to put
Dim RDPItems() As String = IO.File.ReadAllLines(MyDocsDir & "\RDPservers.txt")
outside of a sub, and instead just inside your class. This will ensure that both the click handler and your other sub where you populate the list box can both read from it.

Finding a specific line from a text file and displaying it in a TextBox

I'm currently making a little dictionary application in VB.NET. I have a text file with the words in it and the definition next to it separated by a comma. I am struggling to find a way to display the definition in a TextBox after the user searches for the word.
This is the code I have used to parse the file into a ListBox to show all the words. I haven't done anything with the definition as I'm struggling to get this to work:
Dim i As Integer = 0
Dim line As String
For Each line In File.ReadAllLines("C:\Users\Ben\Desktop\My Project\Swift Word\Words.txt")
Dim parts As String() = line.Split(New Char() {","c})
Dim part As String
For Each part In parts
Console.WriteLine(1)
Next
i += 1
Next