2013-11-28 41 views
0

假设我有一个文件,它包含以下内容:如何从文件中读取某些数据并将其显示出来?

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 
+2

我建议你仔细阅读[这篇文章](http://mattgemmell.com/2008/12/08/what-have-you-tried/) –

+0

@HighCore如果我只是尝试阅读整个文件而不是? – puretppc

+0

然后您需要在问题中发布当前代码,并指定您遇到问题的代码的哪些部分,以及哪些/哪些不工作以及您的预期结果如何。 –

回答

2

首先,删除StreamReader的东西,并留下这个:

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

(请确保你在里面输入正确的文件路径!)

其次,由于你的数据文件有两个Enter S离开,让我们的这种优势。让我们将字符串分割成份这2分进入,然后除以重新每个输入有每场比赛的细节到一个单一的记录,为此,我们将这个变量方便地定义:

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)); 
+0

我试过Lambda语法,但它给了我2个错误。 – puretppc

+0

@puretppc你需要更具体。你得到什么错误?我在我身边工作得很好。 –

+0

@puretppc我使用'e'作为lambda表达式参数,将其改为另一个字母或变量名称,因为您已经有一个'e',它是Button事件参数。 –

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. 
    } 
} 
+0

我编辑了我的第一篇文章,我试了你的代码。但由于某种原因,它似乎没有滤除任何东西。相反,它几乎与我试图读取整个文件相同 – puretppc

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;} 
} 
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); 
    
相关问题