Create 2D array from txt file

Ok, so I managed to read in the .txt file ... now I am trying to figure out how best to convert this information to a 2D array.

My text file (the first two numbers contain the height and width):

5
5
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
0,1,1,1,0
1,1,1,1,1

      

My C # / XNA:

string fileContents = string.Empty;
try
{
    using (StreamReader reader = new StreamReader("Content/map.txt"))
    {
        fileContents = reader.ReadToEnd().ToString();
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

      

Now what I need to do next is determine the size of the 2D array of maps and then fill in the input values ​​... this is where I got a little stuck and found various ways I can get through but I don't think any of them were terrible neat.

What I was trying to do was to have one loop that breaks on a new line ... and then the next loop that is comma separated.

Is this the best way to do it ... or are there better alternatives?

+3


source to share


3 answers


The code below does not require the first lines in the sample .CSV file:

5
5

      



I would prefer it this way, but as a consequence, the code below reads the file twice. Instead, a slight modification is required using the first two rows in your example.

private int[,] LoadData(string inputFilePath)
{
  int[,] data = null;

  if (File.Exists(inputFilePath))
  {
    Dictionary<string, int> counts = GetRowAndColumnCounts(inputFilePath);

    int rowCount = counts["row_count"];
    int columnCount = counts["column_count"];

    data = new int[rowCount, columnCount];

    using (StreamReader sr = File.OpenText(inputFilePath))
    {
      string s = "";
      string[] split = null;

      for (int i = 0; (s = sr.ReadLine()) != null; i++)
      {
        split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        for (int j = 0; j < columnCount; j++)
        {
          data[i, j] = int.Parse(split[j]);
        }
      }
    }
  }
  else
  {
    throw new FileDoesNotExistException("Input file does not exist");
  }

  return data;
}

private Dictionary<string, int> GetRowAndColumnCounts(string inputFilePath)
{
  int rowCount = 0;
  int columnCount = 0;

  if (File.Exists(inputFilePath))
  {
    using (StreamReader sr = File.OpenText(inputFilePath))
    {
      string[] split = null;
      int lineCount = 0;

      for (string s = sr.ReadLine(); s != null; s = sr.ReadLine())
      {
        split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        if (columnCount == 0)
        {
          columnCount = split.Length;
        }

        lineCount++;
      }

      rowCount = lineCount;
    }

    if (rowCount == 0 || columnCount == 0)
    {
      throw new FileEmptyException("No input data");
    }
  }
  else
  {
    throw new FileDoesNotExistException("Input file does not exist");
  }

  Dictionary<string, int> counts = new Dictionary<string, int>();

  counts.Add("row_count", rowCount);
  counts.Add("column_count", columnCount);

  return counts;
}

      

0


source


This can be done with LINQ, but it is practical if you want to (accept) an array int[][]

instead of a straight 2D one int[,]

.



int[][] data = 
    File.ReadLines(fileName)
    .Skip(2)
    .Select(l => l.Split(',').Select(n => int.Parse(n)).ToArray())
    .ToArray();

      

+5


source


Here's a solution that seems to work with.

int[,] txtmap;
int height = 0;
int width = 0;
string fileContents = string.Empty;

try
{
    using (StreamReader reader = new StreamReader("Content/map.txt"))
    {
        fileContents = reader.ReadToEnd().ToString();
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

string[] parts = fileContents.Split(new string[] { "\r\n" }, StringSplitOptions.None);
for (int i = 0; i < parts.Length; i++)
{
    if (i == 0)
    {
        // set width
        width = Int16.Parse(parts[i]);
    }
    else if (i == 1)
    {
        // set height
        height = Int16.Parse(parts[i]);

        txtmap = new int[width, height];
    }

    if (i > 1)
    {
        // loop through tiles and assign them as needed
        string[] tiles = parts[i].Split(new string[] { "," }, StringSplitOptions.None);
        for (int j = 0; j < tiles.Length; j++)
        {
            txtmap[i - 2, j] = Int16.Parse(tiles[j]);
        }
    }
}

      

0


source







All Articles