Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.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中的空行、空行或空行#_C#_Streamreader_Unexpectendoffile - Fatal编程技术网

C# 如何正确处理C中的空行、空行或空行#

C# 如何正确处理C中的空行、空行或空行#,c#,streamreader,unexpectendoffile,C#,Streamreader,Unexpectendoffile,我有一些C#代码正在处理一个文本文件,我似乎无法让它在空白或空(空白)行中正常工作 我的代码: while (!file.EndOfStream) { line = file.ReadLine(); bool isComment = (line[0] == '/') && (line[1] == '/'); bool isPoint = (line[0] == '(') &a

我有一些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做事情。如果这行是注释行或空白行,我希望它什么也不做。如果它注意到括号,我希望它假设它是一个向量3并解析它。最后,如果这条线不是这些,我希望它完全停止。以下是我刚刚用记事本创建的示例文本文件:

//This is a comment
// ... and so is this!
(0, -1.5, 3)
(1, 4, 1.23)

(3, 5, 2)
请注意,第二个和第三个矢量3之间存在间隙。在这种情况下,该行是完全空的,它不包含空格或任何内容,我只需在记事本中按[Enter][Enter]。当我的脚本到达这一行时,它似乎会触发file.EndOfStream boolean。。。。但这不是文件的结尾!我怎样才能解决这个问题?我的while循环是否有更合适的条件?我还试着读入这行代码,并检查它是否作为while条件为null,这是一种更流行的方法,但这种方法对我的情况也不起作用


**注意:“文件”是StreamReader**

类型的变量,David是正确的。我遇到了一个索引超出范围的异常。以下是我的更正和工作代码:

        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);
            }
        }

这与其说是一个答案,不如说是一个风格说明,尽管这也会阻止你看到的问题

首先,使用
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);
    }
}
公共类程序
{
公共静态void Main()
{
列表结果=新列表();
使用(var file=System.IO.file.OpenText(@“C:\temp\test.txt”))
{
弦线;
而((line=file.ReadLine()?.Trim())!=null)
{
//跳过空行和注释
if(line==string.Empty | | line.StartsWith(“/”)
继续;
//将所有其他行解析为向量,出现错误时退出程序
尝试
{
Vector3矢量=解析矢量(直线);
结果:添加(向量);
}
捕获(格式化异常)
{
WriteLine(“第{0}行的分析错误”,第行);
投掷;
}
}
}
foreach(结果中的var v)
Console.WriteLine(({0},{1},{2})”,v.X,v.Y,v.Z);
}
//分析格式为“(x,y,z)”的字符串,全部作为浮点
//在出现任何错误时引发FormatException
公共静态向量3 ParseVector(字符串文本)
{
如果(!text.StartsWith(“(”)| |!text.EndsWith(“)”)
抛出新的FormatException();
string[]parts=text.Substring(1,text.Length-1).Split(',');
如果(零件长度!=3)
抛出新的FormatException();
float x=float.Parse(部分[0]);
float y=float.Parse(部分[1]);
float z=float.Parse(第[2]部分);
返回新矢量3(x,y,z);
}
}

如果不希望使用异常,可以返回null或使用
TryParse
方法使用的模式,返回布尔成功/失败指示符,并使用
out
参数将结果写入。我更喜欢这种情况下的例外。

空字符串和完全由空白组成的字符串不是一回事。新行是一个空白字符,如果要检查空字符串、空字符串或纯空白字符串,请使用
string.IsNullOrWhitespace
。我认为它不会触发file.EndOfStream,但它会引发异常,您只需使用空catch块来处理该异常。这是因为您首先检查了
行[0]
,但若该行为空,则超出范围。如果性能不重要,你可以试试正则表达式。好的,我不知道这个。。。。所以“空”行是这样的:string line=“”?我想,如果你的定义成立,我永远不会在文件中得到一个空行,只有空格或null。我的想法正确吗?我怀疑它在
EndOfStream
检查中失败了,它几乎肯定会退出,因为
if(!isComment&&!isPoint&&!isWhiteSpace){Application.Quit();}
Steve:如果一行不是注释,空格/空白,或者Vector3。您可以将此发布到代码审阅以获得一些改进建议。我知道存在一些低效。我只是高兴地发现了更致命的问题。这不是生产代码,是我个人使用的。我建议使用CR进行学习和个人发展。比改进一段代码重要得多。足够公平了。我可以在哪里提交?我想你在这里谈论的是一个特定的位置,所以这里有一个代码复查堆栈