【问题标题】:Read lines from text file, check content fulfills criteria从文本文件中读取行,检查内容是否符合标准
【发布时间】:2015-08-27 04:04:41
【问题描述】:

嘿,我对 C# 还很陌生,所以我只是在试验如何利用它来执行任务。 我希望它通过一个文本文件并确保每一行都是正确的,文本文件的示例格式是:

;irrelevant
;ignored

table Driver
number 123
name Name123
chassis Mondeo
rank 1
race_image 100
body_style ccar
wheel_basename vauxhall
end

table Driver 
number 178
name Dan#178
chassis XJS
rank 1 
race_image 100 
body_style ccar 
end

table Driver
number 76
name Timmy76!
chassis Lexus
rank 1
race_image 100
body_style ccar
wheel_basename lexb
end
end

它需要忽略空白行,或者只有一个空格的行,并且不区分大小写。虽然它正在通过,但在它检查每一行之后,我希望它在控制台窗口上显示它,这样一旦它发现不正确的东西,它就可以向用户显示错误在哪里;所以在它发现问题之前会有一个恒定的行流。

它需要遍历并检查每个部分。

  • 如果存在“表驱动程序”,请检查下一行,否则停止并通知用户
  • 检查“数字”,然后检查实际数字是否为 1 - 3 位数字,否则停止并通知用户
  • 检查'name',后面的实际name值可以是任何值,否则停止并通知用户
  • 检查 'chassis' 后的实际底盘值必须是列表中的指定字符串,否则停止并通知用户
  • 检查“排名”,然后检查实际排名数字是从 1 到 10,否则停止并通知用户
  • 如果存在“race_image 100”,请检查下一行,否则停止并通知用户
  • 如果存在“body_style ccar”,请检查下一行,否则停止并通知用户
  • wheel_basename 行是可选的
  • 如果存在“wheel_basename”,则检查列表中指定字符串后的值,否则停止并通知用户
  • 如果“wheel_basename”不存在,请检查下一行
  • 如果有 2 个端点,每个端点位于不同的行,那么可能会有一个“goto”函数并显示一条检查完成消息
  • 如果只有 1 个结束,则需要在下一个驱动程序表上再次启动该过程

我现在编写的代码会跳过以分号开头的行,就像它应该做的那样。但是当我尝试让它检查“表驱动程序”时,它会再次从文本文件的开头读取

using (StreamReader textFile = new StreamReader("Drivers.txt"))
{
    foreach (var line in File.ReadLines("Drivers.txt"))
        if (line.StartsWith(";"))
        {
            Console.WriteLine(line);
            continue;
        }
    foreach (var line in File.ReadLines("Drivers.txt"))
        if (line.StartsWith("table driver", StringComparison.CurrentCultureIgnoreCase))
        {
            Console.WriteLine(line);
            continue;
        }
        else
        {
            Console.WriteLine("ERROR");
            // Console.ReadLine();
        }
}

【问题讨论】:

  • 它会重新开始,因为您第二次使用 File.ReadLines。另外请修正您的缩进,您缺少一些 {},而且很难理解。
  • XML 会是您更好的选择。将文件写入XML,解析起来很容易
  • 您已加载 Drivers.txt 3 次。而且您还没有使用 textFile 变量。

标签: c# file streamreader


【解决方案1】:

正如其他人所评论的那样,XML 会使这更容易,但是如果更改数据源不是一种选择,这可以很容易地按原样解决。

首先,每次您在文件上启动 foreach 循环时,您都是从头开始。一旦内部循环完成,前一个循环将继续它停止的地方。

例如: 如果你有以下代码:

foreach(string loop1 in File.ReadLines("data.txt"))
{
    Console.WriteLine("loop1: " + loop1);
    foreach(string loop2 in File.ReadLines("data.txt"))
    {
        Console.WriteLine("loop2: " + loop2);
        foreach(string loop3 in File.ReadLines("data.txt"))
        {
            Console.WriteLine("loop3: " + loop3);
        }
    }
}

使用以下数据集:

one 1
two 2
three 3

您的输出将如下所示:

loop1: one 1
    loop2: one 1
        loop3: one 1
        loop3: two 2
        loop3: three 3
    loop2: two 2
        loop3: one 1
        loop3: two 2
        loop3: three 3
    loop2: three 3
        loop3: one 1
        loop3: two 2
        loop3: three 3
loop1: two 2
    loop2: one 1
    .... continued ....

就解析而言,一个简单的解决方案是将您的逻辑放在 switch 语句中。 示例:

foreach(string loop1 in File.ReadLines("data.txt"))
{
    if (String.IsNullOrEmpty(line)) 
    {
        continue;
    }
    if (line.Equals("end"))
    {
        //do stuff
    }
    string[] parts = line.Split(" ");
    if (parts.Length != 2) 
    {
        //do stuff
    }
    switch(line[0])
    {
        case "one":
            if (!line[1].Equals("1"))
            {
                Console.WriteLine("ERROR! One != 1");
            }
            break;
        case "two":
            ....
        default:
            //not recognized. Do stuff
            break;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多