Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 当换行符是分隔符时,是否可以使用String.Split()?_Vb.net_File Io - Fatal编程技术网

Vb.net 当换行符是分隔符时,是否可以使用String.Split()?

Vb.net 当换行符是分隔符时,是否可以使用String.Split()?,vb.net,file-io,Vb.net,File Io,我有一个问题,要求我从输入文件中计算一些东西。问题是,文件中的行不使用任何特殊字符作为分隔符,如、或|。我将在下面展示它 Data Communication 20 Visual Basic 40 我需要写入另一个文件的输出应如下所示: Data communication 20 Visual Basic 40 Total Books : 60 问题是,如何指定分隔符?就像在strArray=strLine.Split(“,”)中有一个符号一样。由于没有可用作分隔符的内容,如何分割

我有一个问题,要求我从输入文件中计算一些东西。问题是,文件中的行不使用任何特殊字符作为分隔符,如
|
。我将在下面展示它

Data Communication 
20 
Visual Basic  
40
我需要写入另一个文件的输出应如下所示:

Data communication 20
Visual Basic 40

Total Books : 60

问题是,如何指定分隔符?就像在
strArray=strLine.Split(“,”)中有一个符号一样。由于没有可用作分隔符的内容,如何分割文件内容?

当然
System.IO.File.ReadAllLines()
将读取整个文件并根据换行符拆分为一个数组,因此您将得到一个包含4个元素的数组。您可以使用触发器布尔值处理它以获得备用行,或者您可以尝试将该行解析为一个数字,如果它起作用,则它是一个数字,如果不起作用,则它是一个字符串。如果是一个数字,则从上一个循环中获取您记住的字符串(使用变量)

Dim arr = File.ReadALlLines(...)

Dim isStr = True
Dim prevString = ""

For Each s as String in arr

  If isStr Then 
    prevString = s
  Else
    Console.WriteLine($"The string is {prevString} and the number is {s}")
  End If

  'flip the boolean
  isStr = Not isStr
Next s

当您可以使用标准方法逐行读取文件时,实际上不需要拆分输入文件中的文本

例如,您可以使用a从源文件中读取行,检查当前行是否仅为文本,或者是否可以转换为数字,使用和排除空行

在这里,当读取的行不是数字时,它将作为
键添加到
字典(字符串、整数)
,除非它已经存在(用于处理源文件中的重复类别)。
如果该行表示一个数字,它将被添加到先前读取的类别
对应的
值中,存储在名为
previousLine
的变量中

此设置可以处理初始空行、文本正文中的空行和重复类别,例如

Data Communication
20 
Visual Basic  
40

C#  
100
Visual Basic  
10
Other stuff
2

C++
10000
Other stuff
1
如果在第一行中找到一个数字,则将其视为一个类别。
添加任何其他检查以处理输入文件的不同结构

Imports System.IO
Imports System.Linq

Dim basePath = "[Path where the input file is stored]"
Dim booksDict = New Dictionary(Of String, Integer)
Dim currentValue As Integer = 0
Dim previousLine As String = String.Empty

Using sr As New StreamReader(Path.Combine(basePath, "Books.txt"))

    While sr.Peek > -1
        Dim line = sr.ReadLine().Trim()
        If Not String.IsNullOrEmpty(line) Then
            If Integer.TryParse(line, currentValue) AndAlso (Not String.IsNullOrEmpty(previousLine)) Then
                booksDict(previousLine) += currentValue
            Else
                If Not booksDict.ContainsKey(line) Then
                    booksDict.Add(line, 0)
                End If
            End If
        End If
        previousLine = line
    End While
End Using
现在,您有了一个字典,其中键表示类别,相关值是该类别中所有书籍的总和

您可以将字典的每个KeyValuePair转换为表示键及其值的字符串(
Category:Number
)。
这里,也用于按字母顺序对类别进行升序排序;这可能有用

然后调用以存储生成的字符串。
最后,将一个新字符串附加到文件中,使用写入所有类别中所有书籍的总和。该方法对字典中的所有值求和

Dim newFilePath = Path.Combine(basePath, "BooksNew.txt")

File.WriteAllLines(newFilePath, booksDict.
    Select(Function(kvp) $"{kvp.Key}:{kvp.Value}").OrderBy(Function(s) s))
File.AppendAllText(newFilePath, vbCrLf & "Total Books: " & booksDict.Sum(Function(kvp) kvp.Value).ToString())
输出为:

C#:100
C++:10000
Data Communication:20
Other stuff:3
Visual Basic:50

Total Books: 10173

我使用
File.ReadAllLines
获取包含文件中每一行的数组。由于文件的大小可能大于所示的示例,因此我使用的是
StringBuilder
。这节省了在循环的每次迭代中都必须扔掉并创建一个新字符串的时间

我使用的是引号前面的
$
所指示的插值字符串。这允许您将变量插入到由大括号包围的字符串中

注意
For
循环中的
步骤2
<代码>i
将增加2,而不是默认的1

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim lines = File.ReadAllLines("input.txt")
    Dim sb As New StringBuilder
    Dim total As Integer
    For i = 0 To lines.Length - 2 Step 2
        sb.AppendLine($"{lines(i)} {lines(i + 1)}")
        total += CInt(lines(i + 1))
    Next
    sb.AppendLine($"Total Books: {total}")
    TextBox1.Text = sb.ToString
End Sub

应该可以,但这是一种解析分隔数据的糟糕方法,即使是普通的csv