为什么拆分功能不起作用?

时间:2018-03-12 19:03:45

标签: c# split streamreader

我正在尝试从数据文件中读取文本。每行文字如下所示:

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进行了维度化。错误出现在我上面指定的位置。

6 个答案:

答案 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);