这更像是一个风格说明,而不是一个答案,尽管这也可以防止您遇到的问题。
首先,用一个StreamReader
你打电话时ReadLine
您只会收到一个null
到达文件末尾时的结果。您也不关心行首和行尾的空白,并且可能也不关心完全是空白的行。因此,您可以使用它来测试文件结尾和空行:
string line;
while ((line = file.ReadLine()) != null)
{
line = line.Trim();
if (line == "")
continue;
}
接下来,您需要对开始/结束字符进行一些测试,这些字符在某些情况下仍然会导致问题。具体来说,读取只有一个字符的行中的第二个字符将导致异常。
您可以使用以下命令,而不是对未经测试长度的字符串使用索引StartsWith
and EndsWith
进行测试的方法:
bool isComment = line.StartsWith("//");
bool isPoint = line.StartsWith("(") && line.EndsWith(")");
最后,在解析点值的代码中,您假设任何以(
并以)
其中至少有 2 个逗号,并且文本将正确解析。这是一个糟糕的假设。
处理所有这些问题的更好方法是随时检测和处理每种情况,并将解析功能分解为可以重用的方法
这是我的版本:
public class Program
{
public static void Main()
{
List<Vector3> results = new List<Vector3>();
using (var file = System.IO.File.OpenText(@"C:\temp\test.txt"))
{
string line;
while ((line = file.ReadLine()?.Trim()) != null)
{
// skip empty lines and comments
if (line == string.Empty || line.StartsWith("//"))
continue;
// parse all other lines as vectors, exit program on error
try
{
Vector3 vector = ParseVector(line);
results.Add(vector);
}
catch (FormatException e)
{
Console.WriteLine("Parse error on line: {0}", line);
throw;
}
}
}
foreach (var v in results)
Console.WriteLine("({0},{1},{2})", v.X, v.Y, v.Z);
}
// parse string in format '(x,y,z)', all as floats
// throws FormatException on any error
public static Vector3 ParseVector(string text)
{
if (!text.StartsWith("(") || !text.EndsWith(")"))
throw new FormatException();
string[] parts = text.Substring(1, text.Length - 1).Split(',');
if (parts.Length != 3)
throw new FormatException();
float x = float.Parse(parts[0]);
float y = float.Parse(parts[1]);
float z = float.Parse(parts[2]);
return new Vector3(x, y, z);
}
}
如果您不想使用异常,您可以返回 null 或使用TryParse
方法,返回布尔成功/失败指示器并使用out
将结果写入的参数。在这种情况下我更喜欢例外。