C# 从文本文件读取和解析整数
我试图从文本文件中获取一行整数,并将它们解析为单独的变量。文本文件的设置如下所示: ID:HP:MP:STR:WIS:SPD:GOLD:XP 0:100:50:10:5:12:5:10 我想在它们之间用:符号分开。我在这方面遇到的一个问题是,能够逐行读取文件作为字符串,对其进行解析,然后将解析后的字符串存储为int。以下是我目前正在尝试使用的代码:C# 从文本文件读取和解析整数,c#,parsing,file-io,C#,Parsing,File Io,我试图从文本文件中获取一行整数,并将它们解析为单独的变量。文本文件的设置如下所示: ID:HP:MP:STR:WIS:SPD:GOLD:XP 0:100:50:10:5:12:5:10 我想在它们之间用:符号分开。我在这方面遇到的一个问题是,能够逐行读取文件作为字符串,对其进行解析,然后将解析后的字符串存储为int。以下是我目前正在尝试使用的代码: class monster { string line; string[] mstats; string[] mname;
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);
为什么要使用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];
至于如何让代码正常工作,请尝试在传递给解析之前打印出文本行和每段文本。如果它不是整数,那就是你的问题。好吧,首先要找出错误的输入是什么 如果您希望输入的数据不正确,请使用而不是仅使用。如果您不希望输入数据出错,那么它引发异常的事实可能是恰当的——但您应该检查数据以找出错误所在
我还建议只调用一次解析调用,而不是每次调用。这不像是对每个字段进行不同类型的解析。解析文本输入的一种非常好的方法始终是正则表达式
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;
}
Regex r=新的正则表达式(@“(?\d+):(?\d+):(?\d+):(?\d+):(?\d+):(?\d+):(?\d+);
//环线
怪物m=新怪物();
匹配mc=r.Match(输入);
m、 hp=GetValue(mc.Groups[“hp”]、m.hp);
m、 mp=GetValue(mc.Groups[“mp”],m.mp);
m、 str=GetValue(mc.Groups[“str”]、m.str);
...
//处理提取值的方法
私有静态int GetValue(g组,int回退)
{
如果(g==null)抛出新的ArgumentNullException(“g”);
返回g.Success?转换为32(g.Value):回退;
}
GetValue方法检查提取的值。如果匹配失败(可能是“”或“AB”而不是数字-g。成功为假),您可以按照您想要的方式处理它。以我的方式,我只是使用一个回退值
+1,简单起见。请注意,如果列包含非整数值,
String.Split的值为+1,则这将引发异常。对于此输入,远远优于使用正则表达式。还建议打印文本以查看错误。很明显但很重要。哇,我刚刚意识到我在文本文件顶部的“键”ID为:HP:MP。。。把一切都搞砸了,哈哈。完全忘了它在上面。谢谢大家对清理代码的建议!第一次在这里使用,当我有更多问题时,我一定会回来!哦,老兄,我想问一下文件中是否有标题行,但我想,“不……不可能是这样的!”:)不要说“总是”。也有例外。例如html。