我有一些使用文本文件的C#代码,我似乎无法使用空白或空(空格)行正常工作。
我的代码:
while (!file.EndOfStream)
{
line = file.ReadLine();
bool isComment = (line[0] == '/') && (line[1] == '/');
bool isPoint = (line[0] == '(') && (line[line.Length - 1] == ')');
bool isWhiteSpace = string.IsNullOrEmpty(line);
Debug.Log("Comment: " + isComment + ", Point: " + isPoint + ", WhiteSpace: " + isWhiteSpace + "Value: '" + line + "'");
if (!isComment && !isPoint && !isWhiteSpace) { Application.Quit(); }
else if (isPoint)
{
//Strip parenthesis
line = line.Remove(line.Length - 1, 1).Remove(0, 1);
//break into float array
string[] arr = line.Split(',');
float xVal = float.Parse(arr[0]);
float yVal = float.Parse(arr[1]);
float zVal = float.Parse(arr[2]);
Vector3 currentVector = new Vector3(xVal, yVal, zVal);
results.Add(currentVector);
}
}
你可以看到我碰巧用Vector3做事。如果该行是注释行或空白行,我希望它什么都不做。如果它注意到括号,我希望它假设它是一个Vector3并解析它。最后,如果它不是这些线,我希望它完全停止。这是我用记事本创建的示例文本文件:
//This is a comment
// ... and so is this!
(0, -1.5, 3)
(1, 4, 1.23)
(3, 5, 2)
请注意,第二个和第三个Vector3之间存在差距。在这种特殊情况下,该行是完全空的,它不包含空格或任何东西,我只需在记事本中按[Enter] [Enter]。当我的脚本到达这一行时,它似乎触发了file.EndOfStream boolean ....但它不是文件的结尾!我怎样才能解决这个问题?我的while循环是否有更合适的条件?我也试过读取行并检查它是否为null作为while条件,这是一种更流行的方法来解决这个问题,但这种做法对我的情况也不起作用。
**注意:"文件"是StreamReader **
类型的变量答案 0 :(得分:3)
这更像是一种风格音符,而不是一种答案,尽管这也可以防止你遇到的问题。
首先,当您致电StreamReader
时ReadLine
,当您到达文件末尾时,您只会收到null
结果。你也不关心你的行的开头和结尾的空格,并且可能不关心完全是空白的行。所以你可以用它来测试文件结尾和空行:
string line;
while ((line = file.ReadLine()) != null)
{
line = line.Trim();
if (line == "")
continue;
}
接下来,您对开始/结束字符进行了一些测试,这些测试在某些情况下仍然会导致问题。具体来说,读取只有一个字符的行中的第二个字符会导致异常。
您可以使用StartsWith
和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
参数将结果写入。在这种情况下,我更喜欢例外。
答案 1 :(得分:0)
while (!file.EndOfStream)
{
line = file.ReadLine();
bool isWhiteSpace = false;
bool isComment = false;
bool isPoint = false;
isWhiteSpace = string.IsNullOrEmpty(line);
if (!isWhiteSpace)
{
isComment = (line[0] == '/') && (line[1] == '/');
isPoint = (line[0] == '(') && (line[line.Length - 1] == ')');
}
Debug.Log("Comment: " + isComment + ", Point: " + isPoint + ", WhiteSpace: " + isWhiteSpace + "Value: '" + line + "'");
if (!isComment && !isPoint && !isWhiteSpace) { Application.Quit(); }
else if (isPoint)
{
//Strip parenthesis
line = line.Remove(line.Length - 1, 1).Remove(0, 1);
//break into float array
string[] arr = line.Split(',');
float xVal = float.Parse(arr[0]);
float yVal = float.Parse(arr[1]);
float zVal = float.Parse(arr[2]);
Vector3 currentVector = new Vector3(xVal, yVal, zVal);
results.Add(currentVector);
}
}