读取文本文件直到空格并存储多个值

时间:2016-03-19 04:08:45

标签: c# winforms

我正在创建一个应用程序来读取和显示Pokemon统计数据。目前,我有6个txt文件,每个属性一个。我有6个数组读取每个txt文件并在标签中显示每个stat。

我想将这些信息压缩成一个文本文件,将每个数据分成一个“”,以便将每个Pokemon的数据保存在一行中。

当前代码,如果它有助于更​​好地解释这个想法:

using System;
using System.Windows.Forms;

using System.IO;

namespace Pokedex
{
    public partial class Pokedex : Form
    {
        public Pokedex()
        {
            InitializeComponent();
        }

        //Read stat data from text files into string arrays
        string[] HP = File.ReadAllLines("HP.txt");
        string[] Atk = File.ReadAllLines("Atk.txt");
        string[] Def = File.ReadAllLines("Def.txt");
        string[] SpAtk = File.ReadAllLines("SpAtk.txt");
        string[] SpDef = File.ReadAllLines("SpDef.txt");
        string[] Spe = File.ReadAllLines("Spe.txt");

        private void cbxPokemon_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Get array index of currently selected Pokemon
            int index = cbxPokemon.SelectedIndex;

            //Get integer values out of the string arrays for appropriate use
            int intHP = int.Parse(HP[index]);
            int intAtk = int.Parse(Atk[index]);
            int intDef = int.Parse(Def[index]);
            int intSpAtk = int.Parse(SpAtk[index]);
            int intSpDef = int.Parse(SpDef[index]);
            int intSpe = int.Parse(Spe[index]);

            //Update labels with stat values in string forme, could also assign intStat.ToString()
            lblDexNum.Text = (index + 1).ToString("d3");

            lblHP.Text = HP[index];
            lblAtk.Text = Atk[index];
            lblDef.Text = Def[index];
            lblSpAtk.Text = SpAtk[index];
            lblSpDef.Text = SpDef[index];
            lblSpe.Text = Spe[index];

            lblBST.Text = (intHP + intAtk + intDef + intSpAtk + intSpDef + intSpe).ToString();

            //Update bar width based on stat value
            barHP.Width = intHP;
            barAtk.Width = intAtk;
            barDef.Width = intDef;
            barSpAtk.Width = intSpAtk;
            barSpDef.Width = intSpDef;
            barSpe.Width = intSpe;

            //Disable Previous and Next buttons when they cannot be used
            if (index == 0) { btnPrev.Enabled = false; }
            else { btnPrev.Enabled = true; }

            if (index == cbxPokemon.Items.Count - 1) { btnNext.Enabled = false; }
            else { btnNext.Enabled = true; }
        }

        private void btnPrev_Click(object sender, EventArgs e)
        {
            cbxPokemon.SelectedIndex -= 1;
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            cbxPokemon.SelectedIndex += 1;
        }
    }
}

理想情况下,该文件将包含6个统计信息,例如每行上的“100 90 80 70 60 50”,其中每个值都存储。

有没有一种简单的方法可以读取空格,存储该值,并一直这样做直到行尾?

4 个答案:

答案 0 :(得分:2)

尝试这样的事情:

    static void Main(string[] args)
    {
        //list to store stats
        List<string[]> pokemonStats = new List<string[]>();
        //get a reader on the file
        using (StreamReader reader = new StreamReader("TextFile1.txt"))
        {
            //while we still have lines to read
            while (!reader.EndOfStream)
            {
                //get the line of stats
                string line = reader.ReadLine();
                //split it on the ' ' character and store it in our list of pokemon stats
                pokemonStats.Add(line.Split(' '));
            }
        }

        //we have them all so do something, like print to screen
        foreach (string[] pokemon in pokemonStats)
        {
            foreach (string stat in pokemon)
                Console.Write(stat + " ");
            Console.WriteLine();
        }
        Console.ReadLine();
    }

TextFile1.txt包含的地方;这也恰好是输出......

 1 1 1 1 1 1
 2 2 2 2 2 2
 3 3 3 3 3 3

答案 1 :(得分:2)

是的,这很简单。您可以使用String.Split()方法将行拆分为可解析的部分。

您可以像现在一样阅读统计信息文件,除了您只需要读取一个文件而不是六个文件:

string[] lines = File.ReadAllLines("PokemonStats.txt");

然后,在你的cbxPokemon_SelectedIndexChanged方法中,你可以像这样检索一个神奇宝贝的统计数据:

//Get integer values out of the string for appropriate use
string line = lines[index];
string[] parts = line.Split(' ');

int intHP = int.Parse(parts[0]);
int intAtk = int.Parse(parts[1]);
int intDef = int.Parse(parts[2]);
int intSpAtk = int.Parse(parts[3]);
int intSpDef = int.Parse(parts[4]);
int intSpe = int.Parse(parts[5]);

当然,这假设每行总会有6个整数统计数据,并且它们都将按特定顺序排列。

答案 2 :(得分:1)

  

理想情况下,该文件将包含6个统计信息,例如每行上的“100 90 80 70 60 50”,其中每个值都存储。

所以这个解决方案实际上非常简单,假设你有一个如下所示的文件:

100
90
80
70
60
50

您可以编写如下代码:

public string[] ReadStats(string fileName)
{
   return File.ReadAllLines(fileName);
}

这将返回:

[ "100", "90", "80", "70", "60", "50" ]

这显然是一个过度简化的版本,不会检查文件是否存在,是否有超过6行等等。但是它可以解决这个问题,你可以根据自己的需要进行增强。

主要问题的答案:

  

有没有一种简单的方法可以读取空格,存储该值,并一直这样做直到行尾?

这有点复杂,但这应该有效:

public IEnumerable<string[]> ReadAllPokemonStats(string fileName)
{
     List<string[]> allPokemon = new List<string[]>();
     string[] allStats = new string[6];

     var allText = File.ReadAllText(fileName);

     int nextStatIndex = 0;
     string thisStat;
     for(int i=0; i < allText.Length; i++)
     {
         var nextChar = allText[i];
         if(nextChar == ' ')
         {
             allStats[nextStatIndex] = thisStat;
             nextStatIndex++;
             continue;
         }

         if(nextChar == '\r') 
         {
             allPokemon.Add(allStats);
             nextStatIndex = 0;
             allStats = new string[6];
             continue;
         }

         thisStat += nextChar.ToString();
     }

     return allPokemon;
}

同样,上面的代码并不完美,例如它将整个文件读入内存,因此存在潜在的攻击向量。它也不能确保统计数据实际上是数字,但你的代码也没有(它只会在int.Parse()上爆炸)。但同样,它给了你一般的想法。您可以看到,这种方法实际上要比逐行读取每个统计数据要复杂得多。

答案 3 :(得分:1)

我认为每个文件都是一个列文件,代表一种类型的stat。如果这是正确的,你可以试试这个:

或许创建一个类来表示您正在加载的所有统计信息,然后将其视为数组或字典以获取正确的统计信息或创建单个统计信息文件。

    public class PokemonStat
    {
        public int Hp { get; set; }
        public int Atk { get; set; }
        public int Def { get; set; }
        public int SpAtk { get; set; }
        public int SpDef { get; set; }
        public int Spe { get; set; }
    }

然后在执行文件中:

        var newPokemanData = new Dictionary<int, PokemonStat>();
        var fileNames = new string[] { "Hp.txt", "Atk.txt", "Def.txt", "SpAtk.txt", "SpDef.txt", "Spe.txt" }

        foreach (var fileName in fileNames)
        {
            var lineNumber = 0;

            using (var stream = new StreamReader(fileName))
            {
                while (!stream.EndOfStream)
                {
                    var singleStat = stream.ReadLine();

                    if (!newPokemanData.Keys.Contains(lineNumber))
                    {
                        newPokemanData.Add(lineNumber, new PokemonStat());
                    }


                    switch(fileName)
                    {
                        case "Hp.txt":
                            newPokemanData[lineNumber].Hp = int.Parse(singleStat);
                            break;
                        case "Atk.txt":
                            newPokemanData[lineNumber].Atk = int.Parse(singleStat);
                            break;
                        case "Def.txt":
                            newPokemanData[lineNumber].Def = int.Parse(singleStat);
                            break;
                        case "SpAtk.txt":
                            newPokemanData[lineNumber].SpAtk = int.Parse(singleStat);
                            break;
                        case "SpDef.txt":
                            newPokemanData[lineNumber].SpDef = int.Parse(singleStat);
                            break;
                        case "Spe.txt":
                            newPokemanData[lineNumber].Spe = int.Parse(singleStat);
                            break;
                        default:
                            Console.WriteLine("Error");
                            break;
                    }

                    lineNumber++;

                }
            }
        }


        using (var unifiedStats = new StreamWriter("unifieldFile.txt"))
        {

            foreach (var line in newPokemanData.Keys)
            {
                //write to a file
                unifiedStats.WriteLine(newPokemanData[line].Hp.ToString() + " " +
                                        newPokemanData[line].Atk.ToString() + " " +
                                        newPokemanData[line].Def.ToString() + " " +
                                        newPokemanData[line].SpAtk.ToString() + " " +
                                        newPokemanData[line].SpDef.ToString() + " " +
                                        newPokemanData[line].Spe.ToString() + " "                                         
                    );

            }
        }
        //