Прочитать строки из текстового файла, проверить содержимое на соответствие критериям

Эй, я новичок в 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 цифр, иначе остановитесь и сообщите пользователю
  • Проверьте «имя», фактическое значение имени после может быть любым, иначе остановитесь и сообщите пользователю
  • Проверьте фактическое значение шасси «шасси» после того, как оно должно быть указанной строкой из списка, иначе остановитесь и сообщите пользователю
  • Проверьте «ранг», затем проверьте, что фактический номер ранга находится в диапазоне от 1 до 10, иначе остановитесь и сообщите пользователю
  • Если присутствует «race_image 100», проверьте следующую строку, иначе остановитесь и сообщите пользователю
  • Если присутствует 'body_style ccar', проверьте следующую строку, иначе остановитесь и сообщите пользователю
  • Строка wheel_basename необязательна.
  • Если присутствует 'wheel_basename', проверьте значение после указанной строки из списка, иначе остановитесь и сообщите пользователю
  • Если «wheel_basename» отсутствует, проверьте следующую строку
  • Если есть 2 конца, каждый в другой строке, то, возможно, будет функция «перейти» и отобразится сообщение о завершении проверки.
  • Если есть только 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();
        }
}

person user3098131    schedule 13.12.2013    source источник
comment
Это начинается снова, потому что вы используете File.ReadLines во второй раз. Также, пожалуйста, исправьте свой отступ, у вас отсутствуют некоторые {}, и за ними довольно сложно следить.   -  person Pierre-Luc Pineault    schedule 13.12.2013
comment
XML будет лучшим выбором для вас. Запишите файл в XML, его будет легко разобрать   -  person Shaharyar    schedule 13.12.2013
comment
Вы загрузили Drivers.txt 3 раза. А также вы не использовали переменную textFile.   -  person vahnevileyes    schedule 13.12.2013


Ответы (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;
    }
}
person J.D.    schedule 26.08.2015