【问题标题】:VB storing text from txt file to 2D array using Comma DelimiterVB使用逗号分隔符将文本从txt文件存储到二维数组
【发布时间】:2013-11-21 13:36:12
【问题描述】:

我一直在寻找答案,但努力将我的发现融入我的代码/文本文件中。

我有这个文本文件;
20,本
10,戴夫
7、鲍勃

分数和名字。

我想把文本文件中的数据拉到一个二维数组中,例如:

数组(0, 0)
数组(1, 0)
数组(0, 1)
数组(1, 1)
数组(0, 2)
数组(1, 2)

这将转化为;

数组(20)
数组(本)
数组(10)
数组(戴夫)
数组(7)
数组(鲍勃)

提前致谢

【问题讨论】:

  • 你为什么不为此使用一个类?例如 Player 具有两个属性:Name As StringScore As Int32。然后你可以创建一个List(Of Player)。这比摆弄索引更具可读性、可重用性和可维护性,而且更不容易出错。
  • 同意...除非这是为了家庭作业并且您需要使用二维数组?
  • 感谢蒂姆的回复。我应该提到我对 VB 很陌生(几个小时左右)。我的计划是让玩家玩游戏,当游戏结束时询问玩家他们的名字。并将其与乐谱一起存储在文本文件中。然后可以从文本文件中提取排行榜并以不同的形式显示
  • 不,没有作业。只是我正在尝试的东西。
  • @Idle_Mind -- 你不觉得使用 XMLSerializer 是多余的吗?他已经说过他很新,这对他来说将是一个相当大的学习曲线。在这种情况下,在 System.IO 中使用 .NET 的内置文本文件操作功能会更有意义。使用 System.IO.File.ReadAllLines() 将数据拉入数组,然后实例化您建议的类对于初学者来说会容易得多。

标签: arrays vb.net file text 2d


【解决方案1】:

正如我在评论中提到的,我会为此使用一个类。

例如 Player 具有两个属性:Name As StringScore As Int32。然后你可以创建一个List(Of Player)。这比摆弄索引更具可读性、可重用性和可维护性,而且更不容易出错。

Public Class Player
    Public Property Name As String
    Public Property Score As Int32
End Class

这是一个可读的 LINQ 查询,它从文本文件中的行初始化 List(Of Player)

Dim allPlayers = From line In System.IO.File.ReadLines("path")
                 Let Columns = line.Split(","c)
                 Where Columns.Length = 2
                 Let Score = Int32.Parse(Columns(0).Trim())
                 Let Name = Columns(1).Trim()
                 Select New Player With {.Score = Score, .Name = Name}
Dim playerList As List(Of Player) = allPlayers.ToList()

如果您需要数组,请使用 ToArray 而不是 ToList

您可以通过索引器(list(0)) 或通过 LINQ 方法像数组一样访问 alist:

Dim firstPlayer As Player = playerList.FirstOrDefault()  ' is Nothing if there are no players '
Console.WriteLine("Name of the player: " & firstPlayer.Name)
Console.WriteLine("His score is: " & firstPlayer.Score)

或在循环中:

For Each player In playerList
    Console.WriteLine("Player {0} has scored {} points.", player.Name, player.Score)
Next

顺便说一句,LINQ 有助于保持代码的可读性,在底层它还使用循环。所以你可以简单地使用OrderByDescendending按分数对你的球员进行排序,并输出得分最高的前3名:

Dim best3Players = From player In playerList
                   Order By Player.Score Descending
                   Take 3
                   Select String.Format("{0}({1})", player.Name, player.Score)
Dim output = String.Join(", ", best3Players)
Windows.Forms.MessageBox.Show(output) ' since you have mentioned messagebox '

【讨论】:

  • 再次感谢蒂姆,我已经完成了这项工作,并且似乎将数据拉入了“列表”。我刚刚在 Visual Studio 2010 中发现了 Autos 窗口,其中包含每个玩家和得分配对。如何使用这些名称和分数。例如;在 msgbox 中显示名称或分数。我试过 MsgBox(0, Name, Score), MsgBox(0.Name, Msgbox(playerList, 0, Name), MsgBox(playerList(0))...
  • @BenBowden:你有没有注意到我已经编辑了我的答案?
  • 蒂姆,这真是太棒了,哈哈。我已经使用了你的第一个、第二个和最后一个代码 sn-p 并且效果很好......只需显示前三名玩家......只花了 6 个小时哈哈。再次感谢,如果还有什么让我陷入困境,我知道该去哪里。
【解决方案2】:

如果您知道文件不会太大,最简单的方法是简单地使用File.ReadAllLines 方法,该方法返回一个单维字符串数组,文件中每行包含一个项目。然后,您可以遍历每一行并使用 String.Split 方法将这两个值从该行中分离出来,例如:

Dim lines() As String = File.ReadAllLines("leaderboard.csv")
Dim values(lines.Length - 1, 1) As String
For i As Integer = 0 to lines.Length - 1
    Dim parts() As String = lines(i).Split(","c)
    values(i, 0) = parts(0)
    values(i, 1) = parts(1)
Next

但是,如果您创建一个类来存储每一行​​的所有数据,那就更好了,如下所示:

Public Class LeaderboardEntry
    Public Property PlayerName As String
    Public Property Score As Integer
End Class

然后,您可以将值加载到这些对象的列表中,如下所示:

Dim entries As New List(Of LeaderboardEntries)()
For Each i As String In File.ReadAllLines("leaderboard.csv")
    Dim parts() As String = lines(i).Split(","c)
    Dim entry As New LeaderboardEntry()
    entry.Score = parts(0)
    entry.PlayerName = parts(1)
    entries.Add(entry)
Next

然后,不要说values(0, 0) 来获取第一个条目的分数,而是说entries(0).Score,这样更易​​读,尤其是在文件的每一行添加更多字段时。有关使用此类的价值的更多信息,请查看我对this question 的回答。

但是请记住,上面的代码假定每一行的格式都正确。如果文件包含任何不包含逗号的行,它将失败。如果您需要处理这种情况,则需要添加一些额外的检查。此外,在上述场景中,玩家名称不能包含任何逗号。处理这种情况的最佳方法是使用正确的 CSV 格式,如下所示:

30,"Doe, John"

然后你的引号需要被转义,等等,在这种情况下,使用 TextFieldParser 类来读取 CSV 文件而不是重新发明轮子是值得的。另一种选择是简单地禁止用户在其名称中输入逗号。但是,如果您采用这种方法,最好为分隔符选择一个不太常见的字符,例如管道符号 (|)。

我建议使用 XML 文件,而不是使用 CSV 文件。然后您可以轻松地存储数据,即使数据变得越来越复杂,也可以使用XmlSerializerXmlDocumentXDocument 对其进行读写。

如果您只需要存储这样的简单值,那么更好的选择可能是使用My.Settings 功能。

【讨论】:

  • 感谢史蒂文的回复。当我第一次尝试蒂姆的建议时,我没有机会尝试你的建议,它奏效了。但是谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
相关资源
最近更新 更多