从文本文件中读取和解析整数

时间:2009-03-21 15:43:00

标签: c# parsing file-io

我正在尝试从文本文件中获取一行整数,并将它们解析为单独的变量。文本文件设置如下:

ID:HP:MP:STR:WIS:SPD:GOLD:XP

0:100:50:10:5:12:5:10

我想用每个之间的符号拆分它们。我遇到的一个问题是能够逐行读取文件作为字符串,解析它们,然后将解析后的字符串存储为整数。这是我到目前为止尝试使用的代码:

class monster
{
    string line;
    string[] mstats;
    string[] mname;
    char[] delimeterChars = {':'};
    int id;
    int i = -1;
    int j = 0;
    int hp;
    int mp;
    int str;
    int wis;
    int spd;
    int gold;
    int xp;

    public monster(int id)
    {
        StreamReader stats = new StreamReader("monsterStats.txt");
        while(i != id)
        {
            i++;
            line = stats.ReadLine();
            mstats = line.Split(delimeterChars);
            j = 0;
            foreach(string s in mstats)
            {
                if (j == 0) id = int.Parse(s);
                else if (j == 1) hp = int.Parse(s);
                else if (j == 2) mp = int.Parse(s);
                else if (j == 3) str = int.Parse(s);
                else if (j == 4) wis = int.Parse(s);
                else if (j == 5) spd = int.Parse(s);
                else if (j == 6) gold = int.Parse(s);
                else if (j == 7) xp = int.Parse(s);
                j++;
            }
        }
        curHp = hp;
        curMp = mp;
        curSpd = spd;
        curStr = str;
        curWis = wis;
    }
}

此代码运行时出现以下错误:

输入字符串的格式不正确。 它引用了代码的这一部分:

if (j == 0) id = int.Parse(s);

3 个答案:

答案 0 :(得分:3)

为什么foreach?怎么样:

id = int.Parse(mstats[0]);
hp = int.Parse(mstats[1]);

等等。事先检查mstats是否足够长。

Linq会让你一次性得到一个整数数组:

int[] fields = line.Split(delimeterChars).Select(s => int.Parse(s)).ToArray();

id = field[0];
hp = field[2];

至于使代码正常工作,请尝试在将文本传递给Parse之前打印出文本行和每段文本。如果它不是整数,那就是你的问题。

答案 1 :(得分:3)

嗯,首先要找出输入不好的内容。

如果您期待错误的输入数据,请使用int.TryParse而不是int.Parse。如果你期望错误的输入数据,那么抛出异常的事实可能是合适的 - 但是你应该检查你的数据以找出错误。

我还建议将解析调用一次而不是在每种情况下。这不像是你为每个字段做了不同类型的解析。

答案 2 :(得分:2)

解析文本输入的一种非常好的方法始终是正则表达式。

Regex r = new Regex(@"(?<id>\d+):(?<hp>\d+):(?<mp>\d+):(?<str>\d+):(?<wis>\d+):(?<spd>\d+):(?<gold>\d+):(?<xp>\d+)");

// loop over lines
Monster m = new Monster();
Match mc = r.Match(input);

m.hp = GetValue(mc.Groups["hp"], m.hp);
m.mp = GetValue(mc.Groups["mp"], m.mp);
m.str = GetValue(mc.Groups["str"], m.str);
...


// method to handle extracted value
private static int GetValue(Group g, int fallback)
{
    if (g == null) throw new ArgumentNullException("g");
    return g.Success ? Convert.ToInt32(g.Value) : fallback;
}

方法GetValue检查提取的值。如果匹配失败(可能是“”或“AB”而不是数字 - g.Success为false),您可以按照自己的方式处理。按我的方式,我只使用后备值。

http://msdn.microsoft.com/en-us/library/hs600312.aspx