чтение из txt-файла и запись в текстовое поле

#vb.net

Вопрос:

Может кто-нибудь помочь мне с этим, я застрял без понятия, что делать дальше

дайте текстовый файл в любом месте компьютера, он содержит 15 различных целых чисел, которые можно повторить, сделайте программу так, чтобы несколько повторений одного числа не печатались отдельно, но каждое число печаталось ровно один раз и рядом с ним записывалось, в каких местах он появился

     Imports System.IO
Public Class form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim povratnaVrijednost As DialogResult
        Dim nazivDatoteke As String
        Try
            OpenFileDialog1.AddExtension = True
            OpenFileDialog1.Multiselect = False
            OpenFileDialog1.Filter = "Tekst datoteke (*.txt)|*.txt;"
            povratnaVrijednost = OpenFileDialog1.ShowDialog()
            If povratnaVrijednost = Windows.Forms.DialogResult.OK Then
                If OpenFileDialog1.CheckFileExists = True And
                OpenFileDialog1.CheckPathExists = True Then
                    nazivDatoteke = OpenFileDialog1.FileName
                    TextBox1.Text = nazivDatoteke
                    Dim citac As New StreamReader(nazivDatoteke)
                    Dim redTeksta As String = ""
                    Do
                        redTeksta = citac.ReadLine()
                        If Not redTeksta Is Nothing Then
                            RichTextBox1.Text = RichTextBox1.Text   redTeksta
                        End If
                    Loop Until redTeksta Is Nothing
                    citac.Close()
                End If
            End If
        Catch ex As Exception
            MsgBox("Greska prilikom otvaranja"   ex.StackTrace.ToString)


        End Try
    End Sub
End Class
 

123

Комментарии:

1. Вам необходимо на самом деле предоставить подробное объяснение конкретной проблемы, с которой вы столкнулись. Недостаточно сказать: «Вот мое задание, вот мой код» и ожидать, что мы возьмем его оттуда. Вам нужно отладить свой код и быть в состоянии ТОЧНО объяснить, как и где он ведет себя не так, как ожидалось, и каковы эти ожидания.

Ответ №1:

Требование № 1:

предоставьте текстовый файл в любом месте компьютера, он содержит 15 различных целых чисел, которые можно повторить

Это требование подразумевает несколько других требований. Во-первых, вы должны прочитать текстовый файл. Во-вторых, ожидается, что вы проанализируете значения в числа (предположительно целые числа).

Вы можете использовать OpenFileDialog (документация) и указать, что он может принимать только текстовые файлы:

 Using browseFileDialog = New OpenFileDialog()
    With browseFileDialog
        .Filter = "*.txt|*.txt"

        If (.ShowDialog() = DialogResult.Ok) Then
            '.FileName will be the text file that the user picked
        End If
    End With
End Using
 

Чтобы прочитать текстовый файл, предполагая, что вам нужна каждая строка, используйте файл.Метод ReadAllLines (документация):

 Using browseFileDialog = New OpenFileDialog()
    With browseFileDialog
        .Filter = "*.txt|*.txt"

        If (.ShowDialog() = DialogResult.Ok) Then
            Dim lines = IO.File.ReadAllLines(.FileName)
        End If
    End With
End Using
 

Для анализа значений используйте массив.Метод ConvertAll (документация) и внутри предиката используют целое число.Метод анализа (документация):

 Using browseFileDialog = New OpenFileDialog()
    With browseFileDialog
        .Filter = "*.txt|*.txt"

        If (.ShowDialog() = DialogResult.Ok) Then
            Dim lines = IO.File.ReadAllLines(.FileName)
            Dim values = Array.ConvertAll(lines, Function(line) Integer.Parse(line))
        End If
    End With
End Using
 

Имейте в виду, что если бы вы хотели проверить, что все строки являются допустимыми числами, вместо того, чтобы предполагать, что это так, этот шаг был бы другим. Однако вы не указали это требование в своем первоначальном сообщении, поэтому я не включаю, как это сделать.

Требование № 2:

сделайте программу так, чтобы несколько повторений одного числа печатались не отдельно, а каждое число печаталось ровно один раз

Вы можете использовать Случайный.Следующий метод (документация) для генерации случайных значений. Обязательно объявите новый экземпляр случайного объекта один раз, чтобы начальное значение было установлено только один раз. Чтобы случайным образом упорядочить значения, используйте метод OrderBy (документация), передающий случайное значение в предикате:

 Private ReadOnly _random As New Random()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Using browseFileDialog = New OpenFileDialog()
        With browseFileDialog
            .Filter = "*.txt|*.txt"

            If (.ShowDialog() = DialogResult.Ok) Then
                Dim lines = IO.File.ReadAllLines(.FileName)
                Dim values = Array.ConvertAll(lines, Function(line) Integer.Parse(line))
                Dim randomlyOrderedValues = values.OrderBy(Function(value) _random.Next())

                RichTextBox1.Text = String.Join(", ", randomlyOrderedValues.ToArray())
            End If
        End With
    End Using
End Sub
 

Комментарии:

1. При Integer.Parse сбое возникает исключение, которое не обрабатывается. Это ваше намерение?

2. @Mary — У меня есть это в моем посте: Имейте в виду, что если бы вы хотели проверить, что все строки являются действительными числами, вместо того, чтобы предполагать, что это так, этот шаг был бы другим. Однако вы не указали это требование в своем первоначальном посте, поэтому я не включаю, как это сделать.

3. Это не мой пост. В таком случае не Function(line) CInt(line) было бы проще?

4. @Mary — это более лаконично, но мне не нравится использовать ключевые слова VB. Джилхинни уже объяснил, почему он использует их в определенных ситуациях, но я уткнулся головой в землю, как птица-дронт.

5. «Функции Visual Basic предназначены для оптимального взаимодействия с кодом Visual Basic, а также делают ваш исходный код короче и проще для чтения. «См. MS Docs по адресу docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/…

Ответ №2:

Значение по умолчанию .AddExtension равно True . Значение по умолчанию .Multiselect равно False . Я упростил If утверждение, сравнив возвращаемое значение .Showdialog напрямую с желаемым DialogResult . Если путь к файлу не существует, в диалоговом окне появится предупреждение.

Всегда охватывайте переменные как можно более узко. Я перемещаю Dim nazivDatoteke значение «кому» внутрь «Если», так как оно больше нигде не используется. StreamReader s требуют Using блока, так как их необходимо утилизировать.

Почему a RichTextBox для текстового файла?

Как вы можете видеть, получить отличительные элементы в массиве легко, достаточно одной строки кода. Что еще сложнее, так это найти индексы в исходном массиве, lines .

Я перебрал все элементы в distinct массиве (на самом деле это IEnumerable(Of String) так, но это не важно для этого кода, просто в моем объяснении проще ввести массив). Я создал a List(Of Integer) для хранения индексов каждого элемента в исходном массиве, lines . startIndex Где FindIndex метод an Array -это местоположение первого вхождения строки.

На каждой итерации Do цикла я ищу совпадения с элементом из lines массива. FindIndex Принимает параметры (исходный массив, индекс для начала, то, что мы ищем). Он останавливается, как только находит совпадение, и возвращает -1, если совпадения не найдены. Вы можете видеть, как этот метод работает, устанавливая точку останова и проверяя значения переменных.

Если совпадение найдено, я добавил это значение в список и изменил startIndex его на позицию, следующую за найденным индексом.

Затем я использовал a StringBuilder для создания строки для отображения. Я выбрал немедленное окно для целей тестирования, но вы можете отобразить sb.ToString его в текстовом поле или добавить в ListBox .

 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    OpenFileDialog1.Filter = "Tekst datoteke (*.txt)|*.txt;"
    If DialogResult.OK = OpenFileDialog1.ShowDialog Then
        Dim nazivDatoteke = OpenFileDialog1.FileName
        TextBox1.Text = nazivDatoteke
        Dim lines = File.ReadAllLines(nazivDatoteke)
        Dim distinct = lines.Distinct
        For Each item In distinct
            Dim lst As New List(Of Integer)
            Dim startIndex = Array.IndexOf(lines, item)
            Do
                Dim FoundIndex = Array.FindIndex(lines, startIndex, Function(line) line = item)
                If FoundIndex = -1 Then
                    Exit Do
                Else
                    lst.Add(FoundIndex)
                    startIndex = FoundIndex   1
                End If
            Loop
            Dim sb As New StringBuilder
            sb.Append(item)
            For Each i In lst
                sb.Append($" ({i})")
            Next
            Debug.Print(sb.ToString)
        Next
    End If
End Sub
 

Этот код отображает отдельные элементы в списке и следует за ними с позициями (индексами) в исходном списке.