C# 将文本文件中的数据加载到词典中
我有一个由文本列表组成的文件,如下所示:C# 将文本文件中的数据加载到词典中,c#,C#,我有一个由文本列表组成的文件,如下所示: ABC Abbey something ABD Aasdasd 第一个字符串的长度始终为3。所以我想循环遍历文件内容,将前3个字母存储为键,其余字母存储为值。我正在删除它们之间的空白和子字符串,如下所示进行存储。键工作正常,但存储值的行返回以下错误ArgumentOutOfRangeException 这正是导致问题的代码 line.Substring(4, line.Length) 如果我调用0和line.length之间的子字符串,它可以正常工
ABC Abbey something
ABD Aasdasd
第一个字符串的长度始终为3。所以我想循环遍历文件内容,将前3个字母存储为键,其余字母存储为值。我正在删除它们之间的空白和子字符串,如下所示进行存储。键工作正常,但存储值的行返回以下错误ArgumentOutOfRangeException
这正是导致问题的代码
line.Substring(4, line.Length)
如果我调用0和line.length之间的子字符串,它可以正常工作。只要我把它称为介于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();
}
}
类程序{
静态弦线;
静态字典站=新字典();
静态void Main(字符串[]参数){
var lines=File.ReadLines(“C:\\Users\\username\\Desktop\\a.txt”);
foreach(行中的变量l){
行=l。替换(“\t”和“);
stations.Add(line.Substring(0,3),line.Substring(4,line.Length));//由此行引起的错误
}
foreach(站点中的KeyValuePair项){
//控制台。写入线(项。键);
Console.WriteLine(项值);
}
Console.ReadLine();
}
}
您需要实际获得的长度小于总行的长度:
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
这是因为文档指定它将抛出一个if:
startIndex
pluslength
表示不在此实例中的位置
签名:
public string Substring(int startIndex, int length)
由于使用了line.Length
,您知道startIndex
加上Length
将是4+line.Length
,这肯定不是此实例的位置
我建议使用:
因此,line.Substring(3)
(归功于@adv12 for)。因为这里您只需要提供startIndex
。当然,您可以使用line.SubString(3,line.Length-3)
,但与往常一样,最好使用库,因为库的作用是使程序不会出错(这不是攻击性的,只需确保减少此任务的脑循环量即可)。但是,请注意,如果出现以下情况,它仍可能抛出错误:
startIndex
小于零或大于此实例的长度
所以最好提供3
小于或等于line.length
的检查
附加建议
也许你应该看看正则表达式。现在,文件中的每个键都包含三个字符。但在不久的将来,有可能出现四个字符。使用regex capture,您可以指定一种模式,这样在解析过程中就不太可能出现错误。我知道这是一个迟来的答案,它没有解决代码的问题,但我觉得其他人已经这样做了。相反,我有不同的方法来制作字典,它根本不涉及子字符串,所以它更健壮,IMHO 只要您能保证这两个值总是由制表符分隔,那么即使键中有更多或更少的字符,这也会起作用。它使用的LINQ应该是.NET3.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);
}
//LINQ
使用System.Linq;
//创建一个字符串[][]数组,其中键列表位于第一个数组位置
//以及第二个表中的值
var lines=File.ReadAllLines(@“path/to/File.txt”)
.Select(s=>s.Split('\t'))
.ToArray();
//你的字典
字典站=新字典();
//循环遍历数组并将键/值对添加到字典中
对于(int i=0;i
希望这是有意义的,并给你另一个考虑;p> 不需要两个参数的版本<代码>“ABC XYZ”。子字符串(4)代码>是
“XYZ”
…@AlexK。谢谢,这是可行的,但我仍然不明白为什么它不适用于当前代码。因为您试图读取字符串末尾以外的内容,所以第二个参数是长度,而不是末尾索引。@Trevor_zam很多人都会犯这个错误,尤其是当他们习惯于Java时。另外,请注意,他正在一行上执行子字符串,而该行已经删除了制表符,因此他确实希望在索引3而不是索引4处开始子字符串。@adv12:确实如此。虽然我认为使用split或regex捕获进行提取通常不太容易出错。另外,请注意,他正在一行上执行子字符串,该行已经删除了制表符,因此他确实希望在索引3而不是索引4处启动子字符串。这不会导致错误,因为OP使用的是string.Length
属性,没有指定固定长度。如果文件包含错误,例如一行只有三个字符,这可能会导致程序崩溃,而忽略行可能是更合理的解决方案;我是说从4开始会给他错误的数据。@Shaharyar+1。一直在考虑第二个参数是结束索引。
// 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);
}