我正在尝试从文本文件中获取一行整数,并将它们解析为单独的变量。文本文件设置如下:
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);
答案 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),您可以按照自己的方式处理。按我的方式,我只使用后备值。