我正在编写一些代码,从大型机获取报告并将其转换为电子表格。
他们无法编辑MF上的代码给我一个分隔文件,所以我很难将其作为固定宽度处理。
现在它工作正常,但我需要在发布测试之前让它更稳定。
我的问题是,在任何给定的数据行中,它可能有三列数字,每个五个字符在第10,16和22位宽。如果在这一个特定的行上,最后两个没有数据cols,它不会被填充空格;相反,字符串的长度将只有14.所以,我不能盲目地拥有
dim s as string = someStream.readline
a = s.substring(10, 5)
b = s.substring(16, 5)
c = s.substring(22, 5)
因为当它超过字符串的长度时它会窒息。
我知道我可以在处理每一行之前测试字符串的长度,并且 使用计数器和循环自动填充一些vsariables,并使用计数器* theWidthOfTheGivenVariable来跳转,但这个项目是一个开始的狗(来吧!将报告转换成电子表格?),但有许多不同类型的行(它不仅仅是一个网格),而且代码变得越来越难看。我希望这对于在我之后得到这个的可怜的傻瓜来说是干净,清晰和可维护的。
如果重要的话,here's my code so far(目前真的很苛刻)。你可以在processSection #data subs
中看到我/她的一些白痴所以,我想知道
1)有没有一种方法可以让.NET在读取字符串结尾时没有将string.substring包含在try ... catch中?
和
2)在这种情况下编写一个新的字符串类是否合适,该字符串继承自其中包含更友好的子字符串函数的字符串?
ETA:感谢所有人的建议和知识。我会选择扩展名。 希望这些年中的其中一年,我会得到足够的回报,以实物支付给某人。 :)
答案 0 :(得分:3)
我会以不同的方式实现整个事情 -
现在,您必须至少解析三次从大型机发送的每个字符:一次创建字符串,一次解析字符串,一次为每个新变量创建一个字符串。对于固定宽度的行,我会选择一个状态机,逐字符地从流中读取。这并不像听起来那么难,而且它会更好地执行加载,因为它只处理每个字符一次。如果你看一下像String.Format()这样的函数,.Net框架本身就是如何处理这种事情的。
答案 1 :(得分:2)
你不能从String派生,所以选项2是不可能的。我认为无论如何这都是对继承的错误使用,并且ReadLine()
不会返回新字符串的实例......
你可以写一个扩展方法(假设你正在使用VB9) - SafeSubstring
或类似的东西。我不相信框架中已有任何内容。
答案 2 :(得分:2)
您可以编写一个扩展方法来处理您尝试合并的逻辑。我不是一个VB.NET的人,但我认为这是扩展方法的正确语法:
''# Comment to fix broken prettify.js syntax highlighting for attributes in vb.net
<Extension()> _
Public Shared Function SafeSubstring(ByVal aString As String, ByVal startIndex As Integer, ByVal length As Integer) As String
If (startIndex + length > aString.Length) Then
Return aString.Substring(startIndex)
Else
Return aString.Substring(startIndex, length)
End If
End Function
答案 3 :(得分:1)
选项2对于下一个开发人员来说似乎是潜在的危险混淆和严重的痛苦,除非你非常清楚地表明新的API不会阻塞某些阵列操作。 (根据其他人的评论,你不能继承字符串类,但你可以简单地包装它......但是,我不认为这是推荐的方法。)
选项1,try / catch,很难看,如果经常遇到这个错误,它会很慢。
老实说,我认为你最好的方法是明确检查界限:
为了使其清晰易读,您可以使用静态实用程序方法(可能包含在实用程序类中。)这实际上为您提供了两全其美的优势:具有自定义边界检查的清洁代码,它将非常清楚任何人都会在你之后拿起代码。
答案 4 :(得分:1)
也许考虑一种不同的方法并使用某种正则表达式或sscanf-equivalent来解析这些行,并避免使用所有显式子串?