VB_Learner Ответов: 1

Как прочитать определенный столбец текстового файла через текстовое поле и вычислить min max


Дорогие Все,

Я пытаюсь прочитать разные столбцы из текстового файла в соответствии с моей потребностью и вычислить минимальное и максимальное значение для этих столбцов. В текстовом файле минимум 4 столбца. Иногда я читаю столбец 1 и столбец 3, иногда мне приходится читать столбец 2, столбец 5 и так далее. мне нужно указать 2 номера столбца в 2 текстовых полях, прочитать эти столбцы и вернуть минимальные максимальные значения. Текстовый файл разделен пробелами, которые не соответствуют друг другу. Но могут быть столбцы, разделенные как табуляцией, так и пробелами. Поскольку я не являюсь экспертом в VB .net, я бы предпочел иметь что-то простое и понятное. Пока то, что я пробовал, скопировано ниже ... Заранее спасибо !!

Пример текстового файла
1821 20132 194775.0 2664662.5
1821 20372 195375.0 2664662.5
1821 20432 195525.0 2664662.5
1905 24692 206175.0 2665712.5
1905 24932 206775.0 2665712.5
1905 24992 206925.0 2665712.5
S1993 23012 201975.0 2666812.5
S1993 23072 202125.0 2666812.5
1905 25052 207075.0 2665712.5
1905 25112 207225.0 2665712.5
1905 25412 207975.0 2665712.5
1905 25472 208125.0 2665712.5
1907 20132 194775.0 2665737.5
S1907 20312 195225.0 2665737.5
S1907 20372 195375.0 2665737.5

Что я уже пробовал:

Dim Textfile As String
        Dim openDlg As New OpenFileDialog

        If openDlg.ShowDialog() = DialogResult.OK Then
            openDlg.Filter = "txt files (*.txt)| *.txt|All files (*.*)|*.*"
            openDlg.FilterIndex = 2
            openDlg.RestoreDirectory = True
            Textfile = openDlg.FileName
 Using RECfile As New System.IO.StreamReader(Textfile)

Dim maxE As Double = 0
            Dim minE As Double = 99999999
            Dim maxN As Double = 0
            Dim minN As Double = 99999999
            Do While RECfile.Peek() <> -1
 Dim textline As String() = RECfile.ReadLine().TrimStart("S"c).Replace(vbTab & vbTab, vbTab).Split(New Char() {CChar(vbTab)}) // 'comment:  removing the letter "S" which appears in the beginning of the line sometimes and changing all the double tab to single tab and even the spaces to tab to read the columns consistently.

                If CDbl(textline(CInt(Val(Me.eastval.Text)))) > maxE Then
                    maxE = CDbl(textline(CInt(Val(Me.eastval.Text))))
                    Me.MaxvalE.Text = maxE.ToString()

                End If

                If CDbl(textline(CInt(Val(Me.eastval.Text)))) < minE Then
                    minE = CDbl(textline(CInt(Val(Me.eastval.Text))))
                    Me.MinvalE.Text = minE.ToString()

                End If



                If CDbl(textline(CInt(Val(Me.northval.Text)))) > maxN Then
                    maxN = CDbl(textline(CInt(Val(Me.northval.Text))))
                    Me.MaxvalN.Text = maxN.ToString()

                End If
                If CDbl(textline(CInt(Val(Me.northval.Text)))) < minN Then
                    minN = CDbl(textline(CInt(Val(Me.northval.Text))))
                    Me.MinvalN.Text = minN.ToString()

                End If
loop 
End Using

Richard MacCutchan

Не преобразуйте числа в двойные типы. Все значения являются целыми числами, поэтому вы должны обрабатывать их как таковые.

VB_Learner

Спасибо, Ричард, я понял вашу точку зрения и последовал вашему предложению.!!

1 Ответов

Рейтинг:
12

CHill60

Сначала несколько наблюдений...
- Вам нужно настроить диалоговое окно до ты это не после
- Как сказал Ричард в своем комментарии - используйте правильный тип для ваших ценностей
- Это выглядит так, как если бы Вы были классическим программистом VB или VBA, прежде чем рискнуть в VB.NET ... нет необходимости обрабатывать файл построчно или использовать Peek (см. ниже).
- Есть более аккуратный способ использовать функцию разделения (см. ниже)
- Используйте явные методы Try и / или TryParse, а не CDbl или CInt - они более надежны (см. ниже)
- Нет необходимости обновлять текстовые значения текстового поля в цикле - просто сделайте это, как только Вы выработаете минимальные и максимальные значения

Вот моя первая попытка решить эту проблему:

Dim textfile As String
Dim openDlg As New OpenFileDialog

openDlg.Filter = "txt files (*.txt)| *.txt|All files (*.*)|*.*"
openDlg.FilterIndex = 1
openDlg.RestoreDirectory = True

If openDlg.ShowDialog() = DialogResult.OK Then
    textfile = openDlg.FileName

    Dim fileLines() As String = File.ReadAllLines(textfile)

    Dim col1 As List(Of Long) = New List(Of Long)()
    Dim col2 As List(Of Long) = New List(Of Long)()
    Dim col3 As List(Of Double) = New List(Of Double)()
    Dim col4 As List(Of Double) = New List(Of Double)()

    For Each fileLine As String In fileLines

        If fileLine.StartsWith("S") Then fileLine = fileLine.Substring(1)

        Dim items() As String = fileLine.Split(New Char() {CChar(vbTab), " "}, StringSplitOptions.RemoveEmptyEntries)

        Dim lngRet As Long
        Dim douRes As Double
        If Integer.TryParse(items(0), lngRet) Then col1.Add(lngRet)
        If Integer.TryParse(items(1), lngRet) Then col2.Add(lngRet)
        If Double.TryParse(items(2), douRes) Then col3.Add(douRes)
        If Double.TryParse(items(3), douRes) Then col4.Add(douRes)
    Next

    'We now have 4 lists of numbers which we can Sort!
    col1.Sort()
    col2.Sort()
    col3.Sort()
    col4.Sort()

    'The max and min values are in the last and first item respectively
    'Remember that the list uses zero-based indexing!
    MaxvalE.Text = col1.Item(col1.Count - 1).ToString()
    MinvalE.Text = col1.Item(0).ToString()
    MaxvalN.Text = col2.Item(col2.Count - 1).ToString()
    MinvalN.Text = col2.Item(0).ToString()

End If
Я говорю "первая попытка", потому что я, вероятно, продолжу, чтобы увидеть, смогу ли я создать DataTable из файла или, по крайней мере, ввести класс для строк в таблице, чтобы я мог инкапсулировать все поведение (int или double, начинается с S или нет и т. д.). Но это рабочая отправная точка для вас.


VB_Learner

Большое спасибо CHill60 .. это действительно очень простое и прекрасное решение на данном этапе. На самом деле это только начало всей проблемы :P, которую я мог бы объяснить позже после использования этого решения и попытаться сделать следующий шаг!! ..