Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确定合适的子串长度_C#_Io_Substring - Fatal编程技术网

C# 如何确定合适的子串长度

C# 如何确定合适的子串长度,c#,io,substring,C#,Io,Substring,我正在尝试从该文件的箭头位置开始读取列值: 这是我的错误: 我猜这是因为长度值是错误的。 假设我有一个值为:Dog的列 在单词dog后面加上几个空格。我是否必须为dog将长度参数设置为3,或者可以将其设置为6以适应dog之后的空间。这是因为每个列的长度都是固定的。正如您所看到的,一些单词比其他单词小,为了保持一致,我只想将长度设置为最大列长度ex:28是我文件第三列的长度,但并非每次都占用所有28个点-ex:word client只有6个字符长该异常抱怨第一个参数,该参数表明您的文件包含一行

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

这是我的错误:

我猜这是因为长度值是错误的。 假设我有一个值为:Dog的列
在单词dog后面加上几个空格。我是否必须为dog将长度参数设置为3,或者可以将其设置为6以适应dog之后的空间。这是因为每个列的长度都是固定的。正如您所看到的,一些单词比其他单词小,为了保持一致,我只想将长度设置为最大列长度ex:28是我文件第三列的长度,但并非每次都占用所有28个点-ex:word client只有6个字符长

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

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

您正在解析一个固定长度的字段文件,其中每个字段都有一定数量的字符,不管它是否使用所有字符,pos和len数组旨在定义这些字段长度,以便与子字符串一起使用。只要您正在读取的行与预期的字段开始和长度匹配,您就可以了。例如,当您遇到不匹配的行时,似乎是总计行的内容-0TotalRecords:3390315您使用的字段长度定义将不起作用,因为格式已更改,并且行长度甚至可能不相同

为了让这一切顺利进行,我会做一些改变。首先,我将更改您的pos和len数组,以便它们获取整个字段,而不是其中的一部分。您可以使用Trim删除任何前导或尾随空白。根据定义,您的第一个字段将只使用Seq pos 4的最后一个数字len 1,而您的第二个字段将只使用字段的前5个字符,即使它似乎有12个字符的空间

看看这张照片,很难从图片上准确看出它的工作原理,但为了演示的目的,它会起作用:

1 2 3 4 01234567890123456789012345678901234567890 Seq# Field Description 3 BELNR ACCOUNTING DOCUMENT NBR len数组将保存字段的长度,我将其定义为直到下一个字段开头的字符数,如下所示:

Seq# = 6 Field = 12 Description = 28 (using what you have as it is hard to tell
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();
}
如果您想要第四个字段,它将从位置36(位置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 1:

string[] lines = File.ReadAllLines(ofd.FileName).Skip(8)
                 .TakeWhile(l => !l.Contains("Total Records")).ToArray();
上面的代码将跳过前8行,并将所有剩余的行带到第一行,但不包括第一行,以包含字符串中的全部记录

然后你可以这样做:

Seq# = 6 Field = 12 Description = 28 (using what you have as it is hard to tell
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();
}
现在您不必检查Total Records行

当然,如果你的档案中还有其他行,或者在总记录行之后有记录,我很怀疑你是否也要处理这些案件


简而言之,用于提取子字符串的代码只适用于与该特定格式匹配的行,或者更具体地说,具有与这些位置/长度匹配的字段-如果起始位置大于字符串的长度,则超出此范围的任何内容都会给您提供错误的值或引发错误。

如果我们知道发生故障时line和j的值是多少,这会有所帮助。嘿,我如何判断这是否是一个好方法有机会学习如何使用您的工具,以便您可以自己调试简单的问题。查看VisualStudio窗口的底部;应该有一个局部变量选项卡,列出局部变量的当前值。关于使用局部变量,请以文本形式而不是图片形式发布代码。局部变量pos和len的值只需说int[3]该行显示0总记录:3390315 string第一个参数是position,所以它怎么能抱怨说一行显然是您的行之一,但不超过18个字符。这就是异常消息清楚地告诉你的。检查异常命中时的“行”是什么,以便自己查看这一点这是行的值:0总记录:3390315字符串循环甚至没有通过此外观启动抱歉,我认为您没有正确使用调试器。异常消息非常清楚,它发生在循环内部,因此循环肯定正在运行。我在左下角的标签上,标签上写着Local,它给我变量值。你想看看我的实际程序文件吗