Чтение текстового файла и проверка количества столбцов одинаковы для всех строк

У меня есть текстовый файл, который содержит n номеров строк, и каждая строка имеет n количества столбцов с одним разделителем.

Как читать этот текстовый файл построчно и проверять, что все строки имеют одинаковые столбцы. если в какой-либо строке есть дополнительный столбец, покажите номер строки с текстом.

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

147789-00,67,KB08,2007,12,0.000 ,0.000 ,0.000

A22951,67,RN3W,2007,12,0.000 ,0.000 ,0.000

946106-00,67,RN1W,2007,12,0.000 ,0.000 ,0.000,000

A22951,67,RN3W,2007,12,0.000 ,0.000 ,0.000

из 4 строк в 3-й строке есть дополнительный столбец, точно так же могут быть некоторые строки, которые могут иметь дополнительные столбцы. что дополнительные столбцы я хочу найти. или я могу сказать, что если какие-либо строки имеют дополнительный разделитель, тогда он покажет номер строки с текстом.

foreach (string line in File.ReadLines(@"c:\file.txt", Encoding.UTF8))
{
       // how to match the columns    
}

Я иду правильным путем? Пожалуйста, помогите мне.


person Rocky    schedule 04.04.2016    source источник
comment
Что вы подразумеваете под дополнительной колонкой? Имея n + 1 столбец или что-то в этом роде? Поделитесь некоторыми примерами данных, чтобы помочь нам понять.   -  person usamazf    schedule 04.04.2016
comment
пожалуйста, проверьте обновленный вопрос   -  person Rocky    schedule 04.04.2016
comment
Я бы также рекомендовал взглянуть на CSVHelper — › nuget.org/packages/CsvHelper у них есть множество базовых функций, которые вам не пришлось бы выполнять самостоятельно   -  person Boas Enkler    schedule 04.04.2016


Ответы (3)


Если вы не знаете фактическое количество столбцов, но хотите убедиться, что это неизвестное число одинаково для всех строк:

  char delimiter = ',';
  int columnCount = -1; // or put the number if it's known

  var errors = File
    .ReadLines(@"c:\file.txt", Encoding.UTF8) // UTF-8 is default and can be skipped
    .Select((line, index) => {
      int count = line.Split(delimiter).Length;

      if (columnCount < 0)
        columnCount = count;

      return new {
        line = line,
        count = count,
        index = index
      };
    })
    .Where(chunk => chunk.count != columnCount)
    .Select(chunk => String.Format("Line #{0} \"{1}\" has {2} items when {3} expected",
       chunk.index + 1, chunk.line, chunk.count, columnCount));

 // To check if file has any wrong lines:
 if (errors.Any()) {
   ...
 }

 // To print out a report on wrong lines
 Console.Write(String.Join(Envrironment.NewLine, errors));
person Dmitry Bychenko    schedule 04.04.2016
comment
сообщение об ошибке покажет, когда строка будет считаться с 0, что насчет конечного пользователя, они начнут считать с 1, а не с 0 - person Rocky; 04.04.2016
comment
@Rocky: если вы хотите начать отсчет с 1, а не с 0, просто добавьте +1 (см. мое редактирование). То же самое для индекса строки - person Dmitry Bychenko; 04.04.2016
comment
это должен быть chunk.index + 1, а не chunk.count + 1, columnCount + 1 - person Rocky; 04.04.2016
comment
@ Рокки: Верно; нужно больше кофе :) - person Dmitry Bychenko; 04.04.2016
comment
@Rocky: затем поместите число в columnCount вместо текущего -1: например. int columnCount = 8; - person Dmitry Bychenko; 04.04.2016
comment
да понял и сделал. Спасибо большое за вашу помощь. - person Rocky; 04.04.2016
comment
Что делать, если указанный разделитель не совпадает с разделителем текстового файла? - person Rocky; 05.04.2016
comment
@Rocky: тогда вы получите неправильные результаты. Я предположил, что вы знаете разделитель. Измените char delimiter = ',';, если фактический разделитель не является запятой, например. char delimiter = ';';. - person Dmitry Bychenko; 05.04.2016
comment
Можем ли мы добавить какую-либо проверку, чтобы проверить, не соответствует ли предоставленный разделитель разделителю файла, а затем показать, что разделитель не соответствует файлу? Пожалуйста, предложите что-нибудь - person Rocky; 05.04.2016
comment
@Rocky: вряд ли это проверка, это скорее предположение, например. представьте себе такую ​​строку файла: 1,2;3 это запятая или точка с запятой, которая является разделителем? Мы можем подсчитать предполагаемые разделители в первой строке файла, а затем проанализировать числа. - person Dmitry Bychenko; 05.04.2016

char delimiter = ','; // This can be modified 
int numberOfCols = 6; // this will be the number of columns per row

var lines = File
  .ReadLines("Path here")
  .Where(l => l.Split(delimiter).Count() == numberOfCols);

Это даст вам коллекцию, содержащую строку с указанным количеством столбцов; Чтобы собрать недопустимые строки, вы можете использовать следующее:

var invalidLines = File
    .ReadLines("Path here")
    .Select((l, lineNumber) => new { key = lineNumber, value = l })
    .Where(l => l.value.Split(delimiter).Count() != numberOfCols);
person sujith karivelil    schedule 04.04.2016
comment
что делать, если я не знаю количество столбцов - person Rocky; 04.04.2016
comment
Что система хочет сделать if You don't know number of columns - person sujith karivelil; 04.04.2016
comment
система должна получить столбцы на основе разделителя. - person Rocky; 04.04.2016
comment
Отлично; тогда как вы определяете термин extra column - person sujith karivelil; 04.04.2016
comment
если какая-либо строка имеет дополнительный разделитель, это означает, что в строке есть дополнительный столбец - person Rocky; 04.04.2016
comment
В данном примере все строки, кроме 3-й и 4-й, имеют 8 (numberOfCols ) столбцов. вот почему вы говорите, что у них есть дополнительный столбец. будет ли это 8 все время? укажите этот номер в numberOfCols; или подскажите как мне получить 8 - person sujith karivelil; 04.04.2016
comment
именно 3-й и 4-й, имеющие numberOfCols, больше основаны на дополнительном разделителе, вот что мне нужно найти. @DmitryBychenko показывает именно тот пример, который я ожидаю - person Rocky; 04.04.2016

System.IO.StreamReader file = new System.IO.StreamReader("c:\\file.txt");
while((line = file.ReadLine()) != null)
{

}

Теперь вы можете разделить свою строку любым разделителем.

person Divyesh Mistry    schedule 04.04.2016