将数据从文本文件加载到字典中

时间:2016-01-11 17:26:15

标签: c#

我有一个由文本列表组成的文件,如下所示:

ABC Abbey something
ABD Aasdasd

This is the text file

第一个字符串将始终是3的长度。所以我想循环遍历文件内容,将前3个字母存储为Key并保留为值。我正在删除它们之间的空格和Substringing如下存储。键工作正常,但我存储值的行返回错误。的 ArgumentOutOfRangeException

这是导致问题的确切代码。

line.Substring(4, line.Length)

如果我在0和line.length之间调用subString,它可以正常工作。只要我在1和向上之间调用它 - line.length我就会得到错误。老实说,没有得到它,并坚持了几个小时。请一些帮助。

class Program {

        static string line;
        static Dictionary<string, string> stations = new Dictionary<string, string>();

        static void Main(string[] args) {
            var lines = File.ReadLines("C:\\Users\\username\\Desktop\\a.txt");
            foreach (var l in lines) {
                line = l.Replace("\t", "");
                stations.Add(line.Substring(0, 3), line.Substring(4, line.Length));//error caused by this line
            }

            foreach(KeyValuePair<string, string> item in stations) {
                //Console.WriteLine(item.Key);
                Console.WriteLine(item.Value);
            }

            Console.ReadLine();
        }
    }

3 个答案:

答案 0 :(得分:3)

这是因为文档指定它将抛出ArgumentOutOfRangeException if:

  

startIndexlength表示不在此实例中的位置。

签名:

public string Substring(int startIndex, int length)

由于您使用的是line.Length,因此您知道startIndexlength将是4+line.Length,这绝对不是此实例的位置。

我建议使用one parameter version

public string Substring(int startIndex)

因此line.Substring(3)spotting that的@ adv12奖励)。从这里开始,您应该只提供startIndex。当然你可以使用line.SubString(3,line.Length-3),但是一如既往地更好地使用库,因为库是为了使程序变得傻瓜(这不是冒犯性的,只是确保你减少这个任务的大脑周期量) )。但是请注意,如果出现错误,它仍会引发错误:

  

startIndex小于零或大于此实例的长度。

更好地提供3小于或等于line.length ...

的检查

其他建议

也许你应该看一下正则表达式捕获。现在,文件中的每个键都包含三个字符。但是有可能在(接近)未来四个角色是可能的。使用正则表达式捕获,您可以指定一种模式,以便在解析过程中发生错误的可能性较小。

答案 1 :(得分:2)

你需要实际得到的总长度小于:

line.Substring(4, line.Length - 4)    //subtract the chars which you're skipping

你的字符串:

ABC Abbey something
Length = 19
Start  = 4
Remaining chars = 19 - 4 = 15 //and you are expecting 19, that is the error

答案 2 :(得分:1)

我知道这是一个迟到的答案,没有解决你的代码有什么问题,但我觉得其他人已经做过了。相反,我有不同的方法来使字典完全不涉及子字符串,所以它更健壮,恕我直言。

只要您可以保证两个值始终由制表符分隔,那么即使键中有更多或更少的字符,这也会起作用。它使用LINQ,从.NET 3.5开始应该没问题。

// LINQ
using System.Linq;

// Creates a string[][] array with the list of keys in the first array position
// and the values in the second
var lines = File.ReadAllLines(@"path/to/file.txt")
                .Select(s => s.Split('\t'))
                .ToArray();

// Your dictionary
Dictionary<string, string> stations = new Dictionary<string, string>();

// Loop through the array and add the key/value pairs to the dictionary
for (int i = 0; i < lines.Length; i++)
{
    // For example lines[i][0] = ABW, lines[i][1] = Abbey Wood
    stations[lines[i][0]] = lines[i][1];
}

// Prove it works
foreach (KeyValuePair<string, string> entry in stations)
{
    MessageBox.Show(entry.Key + " - " + entry.Value);
}

希望这是有道理的并给你一个考虑的替代方案; - )