如何从文件中读取某些数据并显示它?

时间:2013-11-28 18:57:41

标签: c# file-io

假设我有一个文件,它包含以下内容:

Game Name: Candy Crush
Game Type: Match Three
Game Difficulty Rating: 8

Game Name: Maplestory
Game Type: RPG
Game Difficulty: 6

Game Name: Runescape
Game Type: RPG
Game Difficulty: 6

Game Name: GTA
Game Type: Video
Game Difficulty: 7

如何在消息框中仅发布RPG游戏?我想显示列出的每个RPG游戏的所有数据。

我刚刚尝试过此代码,但它似乎正在显示所有内容。

private void button3_Click(object sender, EventArgs e)
{
    var file = File.ReadAllText("Games.txt");
    var enter = Environment.NewLine;

    var gamestrings = games.Select(x => string.Format("{0}\r\n{1}\r\n{2}", x.Name, x.Type, x.Difficulty));
    MessageBox.Show(string.Join(enter + enter, gamestrings));

    var games = file.Split(new[] { enter + enter }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Split(new[] { enter }, StringSplitOptions.RemoveEmptyEntries)).Select(e => new { Name = e[0], Type = e[1], Difficulty = e[2] }).Where(x => x.Type.Contains("RPG"));
}

给我错误:

Cannot use local variable 'games' before it is declared

A local variable named 'e' cannot be declared in this scope because it would give a     different meaning to 'e', which is already used in a 'parent or current' scope to denote something else

4 个答案:

答案 0 :(得分:2)

首先,删除StreamReader内容,然后保留:

var file = File.ReadAllText(@"c:\Games.txt");

(确保在那里输入正确的文件路径!!)

其次,由于您的数据文件由两个Enter分隔,让我们利用它。让我们将字符串拆分成除以这两个输入的部分然后再将每个输入分开以将每个游戏的细节分成单个记录,为此我们将方便地定义该变量:

var enter = Environment.NewLine;

第三, LINQ 来救援!!

您可以选择Lambda语法:

var games = file.Split(new[] {enter + enter}, StringSplitOptions.RemoveEmptyEntries)
                .Select(x => x.Split(new[] {enter}, StringSplitOptions.RemoveEmptyEntries))
                .Select(e => new {Name = e[0], Type = e[1], Difficulty = e[2]})
                .Where(x => x.Type.Contains("RPG"));

或查询语法:

var games = from g in file.Split(new[] {enter + enter}, StringSplitOptions.RemoveEmptyEntries)
            let gamestrings = g.Split(new[] {enter}, StringSplitOptions.RemoveEmptyEntries)
            let gamerecord = new {Name = gamestrings[0], Type = gamestrings[1], Difficulty = gamestrings[2]}
            where gamerecord.Type.Contains("RPG")
            select gamerecord;

请参阅?现在您有一个强类型的匿名类型列表,其中包含3个属性:

  • 名称
  • 类型
  • 难度

使用这些操作就像它们是常规类一样操作并访问它们的属性,如下所示:

var gamestrings = games.Select(x => string.Format("{0}\r\n{1}\r\n{2}", x.Name, x.Type, x.Difficulty));
MessageBox.Show(string.Join(enter + enter, gamestrings));

答案 1 :(得分:0)

你在代码和问题上遇到了一些问题。

FileStream inputFileStream = new FileStream("Games.txt", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(inputFileStream);

这将打开一个流来读取文件Games.txt中的内容 你关闭了流:

inputFileStream.Close();
reader.Close();

这应该以相反的顺序进行。但是,没有必要同时关闭FileStreamStreamReader。关闭FileStream也会关闭StreamReader

更好的方法是使用using关键字:

using (var inputFileStream = new FileStream("Games.txt", FileMode.Open, FileAccess.Read))
using (var reader = new StreamReader(inputFileStream))
{
  ...
}

这样做你永远不会忘记关闭。

但是所有这些代码在您的程序中都没用。您根本不使用StreamReader 而是阅读Games.txt

中的内容
string contents = File.ReadAllText("Games.txt");

然后显示:

MessageBox.Show(contents);

你真正想做的是逐行阅读:

using (var inputFileStream = new FileStream("Games.txt", FileMode.Open, FileAccess.Read))
using (var reader = new StreamReader(inputFileStream))
{
  while (reader.Peek() >= 0)
  {
    var gameName = reader.ReadLine();
    var gameType = reader.ReadLine();
    var gameDifficulty = reader.ReadLine();
    var emptyLine = reader.ReadLine();

    // Here you'll insert the logic to filter out what you want to show.
  }
}

答案 2 :(得分:0)

这是一种方法:

void Main()
{
string[] lines = System.IO.File.ReadAllLines(@"C:\temp\test.txt");
var test = new List<string>();
foreach (var line in lines)
{
    if (!string.IsNullOrWhiteSpace(line))
    {
        var values = line.Split(':');
        test.Add(values[1].Trim());
    }
}

List<Game> games = new List<Game>();
for (int i = 0;i < test.Count();i = i + 3)
{
    Game game = new Game(); 
    game.Name = test[i];
    game.Type = test[i+1];
    game.Difficulty = test[i+2];

    games.Add(game);
}
var rpgGames = games.Where(w => w.Type == "RPG");
}

class Game {
public string Name {get;set;}
public string Type {get;set;}
public string Difficulty {get;set;}
}

答案 3 :(得分:0)

你也可以试试这个:

  1. 创建一个包含以下属性的游戏类:

    class Game
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public string Difficulty { get; set; }
    }
    
  2. 然后在您的方法中添加以下代码:

    var lines =  File.ReadLines("test.txt");
    var games = new List<Game>();
    
    var currGame = new Game();
    foreach (string line in lines)
    {
        var parts = line.Split(':');
        if (parts.Length == 1)
        {
            games.Add(currGame);
            currGame = new Game();
        }
        else if (parts[0].EndsWith("Name"))
            currGame.Name = parts[1].Trim();
        else if (parts[0].EndsWith("Type"))
            currGame.Type = parts[1].Trim();
        else
            currGame.Difficulty = parts[1].Trim();
    }
    
    var output = string.Join(System.Environment.NewLine, games.Where(x => x.Type == "RPG")
        .Select(x => string.Format("{0} [{1}] => Difficulty: {2}", x.Name, x.Type, x.Difficulty))
        .ToArray());
    Console.Write(output);