-1

我正在尝试从此文件中从箭头位置开始读取列值:

在此处输入图像描述

这是我的错误:

在此处输入图像描述

我猜这是因为长度值是错误的。假设我有一个带有值的列:“Dog”,带有单词 dog 和后面的几个空格。我必须将长度参数设置为 3(对于狗)还是可以将其设置为 6 以容纳 Dog 后面的空格。这是因为每列的长度是固定的。如您所见,有些单词比其他单词小,为了保持一致,我只想将长度设置为最大列长度(例如:28 是我的文件第三列的长度,但并非每次都占用所有 28 个点 - 例如:客户一词只有 6 个字符长

4

2 回答 2

2

该异常抱怨第一个参数表明您的文件包含 < 18 个字符的行

于 2013-10-04T14:56:53.143 回答
2

Robert Levy 的回答对于您所看到的问题是正确的 - 您试图从一个起始位置大于字符串长度的字符串中提取一个子字符串。

您正在解析一个固定长度的字段文件,其中每个字段都有一定数量的字符,无论它是否使用所有字符,posandlen数组旨在定义这些字段长度以用于 Substring。只要您正在阅读的行与预期的字段开头和长度相匹配,您就可以了。一旦您遇到不匹配的行(例如,似乎是总计行 - 0TotalRecords: 3,390,315),您一直使用的字段长度定义将不起作用,因为格式已更改(并且行长度甚至可能不一样)。

有几件事我会改变以使这项工作。首先,我会更改您的poslen数组,以便它们占据整个字段,而不是其中的一部分。您可以使用Trim()它来删除任何前导或尾随空格。根据定义,您的第一个字段将仅采用 Seq# 的最后一个数字(pos 4,len 1),而您的第二个字段将仅采用该字段的前 5 个字符,即使它似乎有大约 12 个字符的空间.

看看这个(很难从图片中准确看出,但为了演示它会起作用):

          1 2 3 4
01234567890123456789012345678901234567890
 序列号字段说明
    3 BELNR 会计文件 NBR

数字是行中每个字符的位置。我会将pos数组定义为字段的开头(第一个字段为 0,之后每个字段的字段标题的第一个字母的位置),所以您将拥有:

序列号 = 0
字段 = 6
描述 = 18

len数组将保存字段的长度,我将其定义为直到下一个字段开头的字符数,如下所示:

序列号 = 6
字段 = 12
描述 = 28(使用你所拥有的,因为很难说

这将使您的数组初始化如下:

int[] pos = new int[3] { 0, 6, 18 };
int[] len = new int[3] { 6, 12, 28 };

如果您想要第四个字段,它将从位置 36 (pos 18 + len 28 = 36) 开始。

第二件事是我会检查循环以查看 Total Records 行是否存在,然后跳过该行(很可能是最后一行):

foreach (string line in textBox1.Lines)
{
    if (!line.Contains("Total Records"))
    {
        val[j] = line.Substring(pos[j], len[j]).Trim();
    }
}

另一种方法是修改原始查询并向其中添加一个TakeWhile子句,以便在您点击 Total Records 之前只取行:

string[] lines = File.ReadAllLines(ofd.FileName).Skip(8)
                 .TakeWhile(l => !l.Contains("Total Records")).ToArray();

以上将跳过前 8 行,并将所有剩余的行带到但不包括字符串中包含“Total Records”的第一行。

然后你可以做这样的事情:

string[] lines = File.ReadAllLines(ofd.FileName).Skip(8)
                 .TakeWhile(l => !l.Contains("Total Records")).ToArray();
textBox1.Lines = lines;

int[] vale = new int[3];
int[] pos = new int[3] { 0, 6, 18 };
int[] len = new int[3] { 6, 12, 28 };

foreach (string line in textBox1.Lines)
{
    val[j] = line.Substring(pos[j], len[j]).Trim();
}

现在您不必检查“总记录”行。

当然,如果您的文件中有其他行,或者“总记录”行之后有记录(我相当怀疑),您也必须处理这些情况。

简而言之,提取子字符串的代码仅适用于与该特定格式匹配的行(或者更具体地说,具有与这些位置/长度匹配的字段)——除此之外的任何内容都会给您不正确的值或引发错误(如果起始位置大于字符串的长度)。

于 2013-10-06T08:13:01.107 回答