简体   繁体   English

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

[英]Reading and parsing integers from a text file

I'm trying to get a line of integers from a text file and parse them into separate variables.我正在尝试从文本文件中获取一行整数并将它们解析为单独的变量。 The text file is set up like this:文本文件设置如下:

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

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

I want to split them with the: symbol in between each.我想在它们之间用: 符号分割它们。 One of the problems I'm having with this is being able to read the file line by line as strings, parsing them, and then storing the parsed strings as ints.我遇到的问题之一是能够逐行读取文件作为字符串,解析它们,然后将解析的字符串存储为整数。 Here is the code I'm attempting to use so far:这是我到目前为止尝试使用的代码:

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;
    }
}

I get the following error when this code runs:运行此代码时出现以下错误:

Input string was not in a correct format.输入字符串的格式不正确。 It references this part of the code:它引用了这部分代码:

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

Why the foreach ?为什么是foreach How about:怎么样:

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

and so on.等等。 With a check beforehand that mstats is long enough.事先检查mstats是否足够长。

A bit of Linq would let you get an array of integers in one shot:一点 Linq 可以让您一次性获得一个整数数组:

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

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

As for getting the code working, try printing out the line of text, and each piece of text just before you pass it to Parse.至于让代码正常工作,请尝试在将文本传递给 Parse 之前打印出文本行和每段文本。 If it's not an integer, that's your problem.如果不是 integer,那就是你的问题。

Well, the first thing is to find out what the bad input was.嗯,第一件事是找出错误的输入是什么。

If you're expecting bad input data, use int.TryParse instead of just int.Parse .如果您预期输入数据错误,请使用int.TryParse而不是仅使用int.Parse If you're not expecting bad input data, the fact that it's throwing an exception is probably appropriate - but you should examine your data to find out what's wrong.如果您没有预料到错误的输入数据,那么它引发异常的事实可能是合适的 - 但您应该检查您的数据以找出问题所在。

I'd also recommend putting the parsing call once rather than in every case.我还建议进行一次解析调用,而不是每次都进行。 It's not like you're doing a different kind of parsing for each field.这不像您正在为每个字段进行不同类型的解析。

A very good way for parsing text input are always regular expressions.解析文本输入的一个非常好的方法总是正则表达式。

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;
}

The method GetValue checks the extracted value. GetValue 方法检查提取的值。 If the match failed (perhaps "" or "AB" instead of a number - g.Success is false) you can handle it the way you want.如果匹配失败(可能是“”或“AB”而不是数字 - g.Success 为假),您可以按照您想要的方式处理它。 In my way i simply use an fallback value.以我的方式,我只是使用后备值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM