简体   繁体   English

C# 使用 txt 文件中特定位置的对象填充二维数组

[英]C# Filling a 2D array with objects from a txt file at specific positions

Im trying to fill a 2D array with a txt file from my computer.我试图用我电脑上的 txt 文件填充二维数组。

I have tried doing this in two different ways but i have not gotten either to work.我试过用两种不同的方式来做这件事,但我没有得到任何工作。

  1. Save objects position number in the file using the following code.使用以下代码在文件中保存对象位置编号。

     for (int row = 0; row < 100; row++) { for (int col = 0; col < 2; col++) { if (cpp[row, col] == null) { break; } else { if (cpp[row, col] == null) continue; save.WriteLine(string.Format("{0}, {1}, {2}, {3}", row + 1, cpp[row, col].RegNumber, cpp[row, col].VehicleTypes, cpp[row, col].TimeOfArrival)); } } }

Second way i have tried is to save the file with the empty lines aswell.我尝试过的第二种方法是用空行保存文件。

 foreach (var temp in cpp)
            {
                if (temp == null) save.WriteLine("");
                if (temp == null) continue;
               save.WriteLine("{{0},{1},{2}", temp.RegNumber, temp.VehicleTypes, temp.TimeOfArrival);
            }

I have gotten nowhere with the load function and i would appreciate any help i can get with this.我在加载功能方面一无所获,我将不胜感激我能得到的任何帮助。 I need to load the file in to my 2D array and the objects have to be assigned to the same position it was before.我需要将文件加载到我的二维数组中,并且必须将对象分配到与之前相同的位置。

The only code i have for the load function is this.我对加载功能的唯一代码是这个。

string[] lines = File.ReadAllLines("CarParkPrague.txt");
            var vehicles = new List<Vehicle>();
            {
                foreach (var line in lines)
                {
                    var values = line.Split(",");
                    Enum.TryParse(values[1], out VehicleType type);
                    var time = DateTime.Parse(values[2]);
                    vehicles.Add(new Vehicle(values[0], type, time)); 
                    
                }
            }

Text file line example = AAA111,CAR,2020-10-11 14:19:04 Or with the position saved = 1,AAA111,CAR,2020-10-11 14:19:04 Can be either, which ever is easiest.文本文件行示例 = AAA111,CAR,2020-10-11 14:19:04 或保存位置 = 1,AAA111,CAR,2020-10-11 14:19:04 可以是任何一个,哪个最简单。

This is a test method that works but it saves the vehicles on first best available spot in the array so its not quite right.这是一种有效的测试方法,但它将车辆保存在阵列中第一个最佳可用位置,因此不太正确。 The text file is in this case saved without a position number.在这种情况下保存的文本文件没有位置编号。 And looks like the first example above.看起来像上面的第一个例子。

static void LoadTestFile() //Loads the array using the test file which is filled with examples.
    {
        string[] lines = File.ReadAllLines("testfile.txt");
        var vehicles = new List<Vehicle>();

        foreach (var line in lines)
        {
            var values = line.Split(",");
            Enum.TryParse(values[1], out VehicleType type);
            var time = DateTime.Parse(values[2]);
            vehicles.Add(new Vehicle(values[0], type, time));
        }

        int counter = 0;
        for (int i = 0; i < 100; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                if (counter >= vehicles.Count)
                    break;

                if (cpp[i, 0] != null)
                {
                    if (cpp[i, 0].VehicleTypes == VehicleType.CAR)
                    {
                        continue;
                    }
                }

                if (vehicles[counter].VehicleTypes == VehicleType.CAR)
                {
                    cpp[i, j] = vehicles[counter++];
                }
                else
                {
                    cpp[i, j] = vehicles[counter++];
                }
            }
        }

Your loading function will crash if you have empty lines, so I can't quite believe it works to read a file with blank lines on.如果您有空行,您的加载功能将崩溃,所以我不太相信读取带有空行的文件会起作用。 The big problem with it though is that it doesn't do anything if it encounters a blank line when really it should be putting a blank (null) vehicle at that position in the list但是它的一个大问题是,如果遇到空行,它不会做任何事情,而实际上它应该在列表中的该位置放置一个空白(空)车辆

Save blank lines if the vehicle is null, and also save dates in a fixed format:如果车辆为空,则保存空行,并以固定格式保存日期:

        foreach (var temp in cpp)
        {
            if (temp == null) 
                save.WriteLine();
            else
                save.WriteLine("{{0},{1},{2}", temp.RegNumber, temp.VehicleTypes, temp.TimeOfArrival.ToString("yyyyMMddHHmmss"));
        }

Load, catering for blank lines by putting no vehicle (null) in that position:通过在该位置不放置车辆(空)来加载、迎合空行:

        string[] lines = File.ReadAllLines("CarParkPrague.txt");
        var vehicles = new List<Vehicle>();
        
        foreach (var line in lines)
        {
            if(string.IsNullOrWhiteSpace(line))
            { 
                vehicles.Add(null);
                continue;
            }
            var values = line.Split(",");
            Enum.TryParse(values[1], out VehicleType type); //should really test this with an if
            var time = DateTime.ParseExact(values[2], "yyyyMMddHHmmss", null);
            vehicles.Add(new Vehicle(values[0], type, time)); 
                
        }
    }

Hopefully you can see how your "if the parking space is empty the vehicle is null and this becomes a blank line during save" is translated back upon load to "if the line is blank then the space is marked as empty by putting a null vehicle there"希望你能看到你的“如果停车位是空的,车辆是空的,这在保存期间变成一个空行”在加载时被转换回“如果该行是空的,那么通过放置一个空车辆来将空间标记为空那里”

Edit;编辑; as you seem to have a fixed number of parking spaces and are using null to represent emptiness, having a collection like a List, which dynamically sizes to fit the contents is perhaps not ideal.由于您似乎拥有固定数量的停车位并且使用 null 来表示空,因此拥有像 List 这样的集合,它可以动态调整大小以适应内容可能并不理想。 Switch to using an array that represents the size of the car park:切换到使用表示停车场大小的数组:

    string[] lines = File.ReadAllLines("CarParkPrague.txt");
    var vehicles = new Vehicle[100];
    
    for (int i = 0; i < lines.Length && i < vehicles.Length; i++)
    {
        var line = lines[i];

        if(string.IsNullOrWhiteSpace(line))
            continue;
        
        var values = line.Split(",");
        Enum.TryParse(values[1], out VehicleType type); //should really test this with an if
        var time = DateTime.ParseExact(values[2], "yyyyMMddHHmmss", null);
        vehicles[i] = new Vehicle(values[0], type, time); 
            
    }
}

Don't forget that the vehicles in the load method should be assigned to the same variable that cpp in the save method represents.不要忘记 load 方法中的vehicles应该分配给 save 方法中cpp表示的相同变量。 Really, you ought to use the same class wide variable in both methods真的,您应该在两种方法中使用相同的类范围变量

Let's start with something that's entirely trivial - mirror the save and load methods.让我们从完全微不足道的事情开始 - 镜像保存和加载方法。 The only thing you really need to add is the dimensions of the array:您真正需要添加的唯一内容是数组的维度:

var rowCount = cpp.GetLength(0);
var colCount = cpp.GetLength(1);

save.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0},{1}", rowCount, colCount));
for (var row = 0; row < rowCount; row++)
{
  for (var col = 0; col < colCount; col++)
  {
    if (cpp[row, col] == null) save.WriteLine();
    else save.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", cpp[row, col].RegNumber, cpp[row, col].VehicleTypes, cpp[row, col].TimeOfArrival));
  }
}

To read this very straight-forward file format, do the same thing in reverse:要读取这种非常简单的文件格式,请反向执行相同的操作:

using (var sr = new StreamReader("CarParkPrague.txt"))
{
  var dimensions = sr.ReadLine()?.Split(',');

  if (dimensions == null 
      || !int.TryParse(dimensions[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var rowCount) 
      || !int.TryParse(dimensions[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var colCount)
     )
    throw new Exception("Invalid dimensions.");

  var cpp = new Vehicle[rowCount, colCount];

  for (var row = 0; row < rowCount; row++)
  {
    for (var col = 0; col < colCount; col++)
    {
      if (!(sr.ReadLine() is {} line) throw new Exception("Unexpected end of file.");
      if (string.IsNullOrWhitespace(line)) continue;

      var values = line.Split(",");
      if (!Enum.TryParse(values[1], out var vehicleType)) throw new Exception($"Unexpected vehicle type '{values[1]}'.");
      if (!DateTime.TryParse(values[2], CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime) throw new Exception($"Invalid time '{values[2]}'.");

      cpp[row, col] = new Vehicle(values[0], type, time); 
    }
  }
}

There's plenty of ways to optimize this, but there's little reason to bother if the resulting file is just a few kilobytes (or even tens of kilobytes).有很多方法可以对此进行优化,但是如果生成的文件只有几 KB(甚至几十 KB),则没有理由打扰。

Thanks for all the help.感谢所有的帮助。 This is a solution that works for my project.这是适用于我的项目的解决方案。 Save file and load in to the 2d array.保存文件并加载到二维数组中。

 static void SaveFile() //Saves the current array using streamwriter.
    {
        Console.Clear();
        StreamWriter save = new StreamWriter("CarParkPrague.txt");
        using (save)
        {
     
            foreach (var temp in cpp)
            {
                if (temp == null) save.WriteLine();
                else
                save.WriteLine("{0},{1},{2}", temp.RegNumber, temp.VehicleTypes, temp.TimeOfArrival);
            }
        }
        Console.WriteLine("File saved succesfully");
        Console.WriteLine("----------------------------------------------------------------");
    }


static void LoadFile() //Loads the array using the saved file.
    {
        try
        {
            string[] lines = File.ReadAllLines("CarParkPrague.txt");
            var vehicles = new List<Vehicle>();
            {
                foreach (var line in lines)
                {
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        vehicles.Add(null);
                        continue;
                    }
                    var values = line.Split(",");
                    Enum.TryParse(values[1], out VehicleType type);
                    var time = DateTime.Parse(values[2]);
                    vehicles.Add(new Vehicle(values[0], type, time)); 
                    
                }
            }
            int counter = 0;
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 2; j++)
                {

                    if (vehicles[counter] == null)
                    {
                        cpp[i, j] = vehicles[counter++];
                    }
                   else if (vehicles[counter] != null)
                    {
                        cpp[i, j] = vehicles[counter++];
                    }
                }
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine(ex);
            Console.WriteLine("File could not be found. Please make sure there is a file named (CarParkPrague.txt) in your folder.");
        }
        Console.Clear();
        Console.WriteLine("File have been loaded succesfully");
        Console.WriteLine("----------------------------------------------------------------");
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM