顺序排列并在文本文件中添加占位符

时间:2018-12-06 04:50:08

标签: c# file

我有一个包含数据的文本文件。一共有3列,每列从文件中的特定位置开始到结束。第一列(300、301、302、304 ...)始终基于数字。第二列是字符串,最后一列是货币。

当前的.txt文件缺少数字(303,305)。 我能够找到丢失的数字并将其添加到数组中,然后将其写入文件中。

我的目标是将所有列数据按顺序写到文本文件中,即使缺少的也是如此。至于第2列和第3列,我希望0成为丢失数据的占位符,并与它自己的列对齐。

我已经关闭,但需要帮助

   //read file
   string[] lines = File.ReadAllLines(FilePath);
   var Numbers = new List<int>();
   int i = 0;
   foreach (var line in lines)
   {
       //get value of first column
       var FirstColumn = line.Substring(0, 3);
       //add it to array
       Numbers.Add(Convert.ToInt32(FirstColumn));
       ++i;
   }
   //find missing numbers add to array
   var result = Enumerable.Range(Numbers.Min(), Numbers.Count);            

   //write to file
   using (StreamWriter file = new StreamWriter(OutPutFile, true))
   {
       foreach (var item in result.ToArray())
       {
           file.WriteLine(item);
       }                
   }


   Console.ReadKey();

当前.txt文件

300     Family Guy      1,123
301     Dexters Lab     456
302     Rugrats         1,789.52
304     Scooby-Doo      321
306     Recess          2,654
307     Popeye          1,987.02

目标:所需的输出.txt文件

300     Family Guy      1,123
301     Dexters Lab     456
302     Rugrats         1,789.52
303     0               0
304     Scooby-Doo      321
305     0               0
306     Recess          2,654
307     Popeye          1,987.02

1 个答案:

答案 0 :(得分:1)

您正在阅读的第一列,而不是其余的。我要做的是创建一个字典,使用第一个数字作为索引,并将其他两个字段填充到System.ValueTuple中(您需要包括ValueTyple Nuget包才能使它起作用)。

首先,我设置了一些东西:

 const int column1Start = 0;
 const int column1Length = 3;
 const int column2Start = 8;
 const int column2Length = 15;
 const int column3Start = 24;

 int indexMin = int.MaxValue;     //calculated during the first
 int indexMax = int.MinValue;     //pass through the file

然后创建字典。 (string, decimal)语法描述了一个2元组,其中包含一个字符串和一个十进制数字(有点像您在高中时所学的有序对)。

 Dictionary<int, (string, decimal)> data = new Dictionary<int, (string, decimal)>();

然后我通过文件的各行,读取数据,并将结果填充到字典中(并计算第一列的最大值和最小值):

 var lines = File.ReadAllLines(fileName);
 foreach (var line in lines) {
     //no error checking
     var indexString = line.Substring(column1Start, column1Length);
     var cartoon = line.Substring(column2Start, column2Length).TrimEnd();
     var numberString = line.Substring(column3Start);

     if (int.TryParse(indexString, out var index)) {
         //I have to parse the first number - otherwise there's nothing to index on
         if (!decimal.TryParse(numberString, out var number)){
             number = 0.0M;
         }
         data.Add(index, (cartoon, number));

         if (index < indexMin) {
             indexMin = index;
         }
         if (index > indexMax) {
             indexMax = index;
         }
     }
 }

最后,我掌握了所有数据,然后从最小值迭代到最大值,然后从字典中提取另外两列:

 for (int i = indexMin; i <= indexMax; ++i) {
     if (!data.TryGetValue(i, out var val)){
         val = ("0", 0.0M);
     }
     Console.WriteLine($"{i,5}  {val.Item1,-column2Length - 2}  {val.Item2, 10:N}");
 }

我的格式与您的格式不太一样(我整理了一下)。你可以做你想做的。我的结果如下:

  300  Family Guy           1,123.00
  301  Dexters Lab            456.00
  302  Rugrats              1,789.52
  303  0                        0.00
  304  Scooby-Doo             321.00
  305  0                        0.00
  306  Recess               2,654.00
  307  Popeye               1,987.02