我正在尝试从数据文件中读取文本。每行文字如下所示:
Group_5, 4911.66, 4910.274, 13781.725, 2018
我想解析字符串,以便我可以将值用于计算。字符串数组Str
仅收集第一个术语Group_5
。
private void button1_Click(object sender, EventArgs e)
{
string Line;
string path = Survey_File.Text;
int i, j;
double X = 0, Y = 0, Z = 0, X_Last = 0.0, Y_Last = 0.0, Z_Last = 0.0, MD = 0, increment;
string[,] StrMatrix = new string[1000000, 3];
string[] Str = new string[5];
string[] Strings = new string[1000000];
string content;
i = j = 0;
StreamReader ReadSurveyFile = new StreamReader(Survey_File.Text);
while ((Line = Convert.ToString(ReadSurveyFile.ReadLine())) != null)
{
Line = Convert.ToString(Line);
Str = Line.Split(',', ',', ',', ',');
Strings[i] = Line;
Str = Strings[i].Split(',');
//X = Convert.ToDouble(Str[1]);
//Y = Convert.ToDouble(Str[2]);
//Z = Convert.ToDouble(Str[3]);
increment = Math.Sqrt((X - X_Last) * (X - X_Last) + (Y - Y_Last) * (Y - Y_Last) + (Z - Z_Last) * (Z - Z_Last));
X_Last = X;
Y_Last = Y;
Z_Last = Z;
MD = MD + increment;
i++;
Console.WriteLine(Str[1]); // Error Here
}
Console.ReadLine();
MessageBox.Show("Measured Depth = "+Convert.ToString(MD));
}
我收到的错误消息是
" IndexOutOfRangeException未处理。"
这对我没有意义,因为我正确地对字符串数组Str
进行了维度化。错误出现在我上面指定的位置。
答案 0 :(得分:2)
您不清楚自己要做什么,但这应该更容易使用。它清除了原始数组和值之间的大部分混乱。
private void button1_Click(object sender, EventArgs e)
{
double X_Last = 0.0, Y_Last = 0.0, Z_Last = 0.0;
double MD = 0.0;
var lines = File.ReadLines(Survey_File.Text).Select(l => l.Split(','));
foreach(var line in lines)
{
double X = double.Parse(line[1].Trim());
double Y = double.Parse(line[2].Trim());
double Z = double.Parse(line[3].Trim());
double XDiff = X - X_Last;
double YDiff = Y - Y_Last;
double ZDiff = Z - Z_Last;
double increment = Math.Sqrt((XDiff * XDiff) + (YDiff * YDiff) + (ZDiff * ZDiff));
MD += increment;
X_Last = X;
Y_Last = Y;
Z_Last = Z;
Console.WriteLine(MD.ToString());
}
Console.ReadLine();
MessageBox.Show("Measured Depth = " + MD.ToString());
}
注意我通常不会宽恕使用Split()
来处理CSV数据。它很慢且容易出错。但是在这种情况下,样本数据似乎相当安全,而Split()在这里是最不受关注的。
答案 1 :(得分:1)
该源文件看起来像一个CSV文件。虽然您可以使用Split解析它们,但我建议您使用合适的CSV阅读器。最新的,当你遇到像逃脱的分离器,折线或多线字段这样的怪异时,简单的拆分就会崩溃。 (破线的情况很可能就是你在这里所拥有的。)
有一个内置的CSV解析器,但在Visual Basic Sourcefiles(https://coding.abel.nu/2012/06/built-in-net-csv-parser/)
中隐藏了一些然而,有很多第三方解决方案,这个似乎特别有希望:http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
如果文件很大(并且您的第三方CSV解析器代码尚未执行此操作),我建议您使用Enumerator approach to itterate over the lines。已知大型CSV文件会像旧的2 GiB一样运行到内存限制中,即使这不是问题,使用枚举器也应该稍快一些。
答案 2 :(得分:1)
你得到的错误是经典的。错误在于您正在尝试使用在执行“Str [1]”时不存在的索引。换句话说,在执行时,'Str'中没有两个项目。
请注意,Str的类型为“string []”(字符串数组 - 请注意,这不是修复数组的大小),并且初始化它指向一个包含5个字符串的数组。但是,当你指定“Str = Strings [i] .Split(',');”时,它会将Str分配给该分割的结果,这将是分割字符串给出的项目大小;并丢弃5个字符串的数组。
由于您一次循环遍历文件的每一行,我的猜测是您到达的行中没有两个以逗号分隔的项目。我的猜测是它可能是你文件中的空行。您可以通过使用调试器来证明这一点,或者在崩溃之前将Console.WriteLine("Line " + i + ":" + Line);
放在行上。
所以尽管有这个问题,斯普利特的工作也很完美。异常的原因是使用索引器而不确定数组中有多少项(这总是IndexOutOfRangeException的原因)。
P.S。 “StreamReader”是一次性的,所以你应该将它放在“使用”块中。
答案 3 :(得分:0)
尝试
Str = Line.Split(',');
而不是
Str = Line.Split(',', ',', ',', ',');
然后Str应该足够长,以便Str [1](“4911.66”)存在,并且应该防止错误。
答案 4 :(得分:0)
您可能不需要这样做:
Line = Convert.ToString(Line); //Already happens in the readline in loop.
Str = Line.Split(',', ',', ',', ','); // do Line.Split(',') instead
从这一点开始,似乎没问题,但我建议做一些事情来验证你是否正确读取了Line。如果你只是得到第一个字。
其次,将Str
初始化的内容并不重要......调用String.Split()
会将Str
分配给包含split方法结果的新数组。< / p>
//Somewhere above:
string[] Str = new string[5];
Strings[i] = Line;
Str = Strings[i].Split(','); //reassigns Str to a new array created by String.Split(',')
答案 5 :(得分:-1)
试试这个:
Str = Line.Split(new char[] {','}, StringSplitOptions.None);