【问题标题】:Create 2D array from txt file从 txt 文件创建二维数组
【发布时间】:2012-03-29 06:56:40
【问题描述】:

好的,所以我已经设法读入了一个 .txt 文件……现在我正在尝试找出将这些信息转换为二维数组的最佳方法。

我的文本文件(前两个数字提供高度和宽度):

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

我的 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);
}

现在我接下来需要做的是定义二维映射数组的大小,然后填充条目值...这是我有点卡住的地方,我找到了可以循环遍历的各种方法数据,但我认为它们中的任何一个都不是非常整洁。

我试图做的是有一个循环由换行符分割...然后另一个循环由逗号分隔符分割。

这是最好的方法吗?还是有更好的选择?

【问题讨论】:

  • 听起来你在正确的轨道上。也许尝试使用扩展方法,例如 ToArray()
  • @JohnSaunders 对不起,我的错。

标签: c# string multidimensional-array xna xna-4.0


【解决方案1】:

下面的代码不需要示例 .CSV 文件中的第一行:

5
5

我更喜欢这种方式,但结果是,下面的代码会读取文件两次。改为使用示例中的前两行进行小修改。

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;
}

【讨论】:

  • 这看起来有点冗长......看看我的解决方案。
  • 是的,你做了我提到的修改。将高度和宽度放在前 2 行中消除了对第二个函数的需要。但是,我不喜欢您的输入文件格式。 这是一种偏好。
  • 嗯...我可以理解...一旦它变大就很难计算列数等...所以自动化会有所帮助。
【解决方案2】:

这是我想出的似乎可行的解决方案。

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]);
        }
    }
}

【讨论】:

    【解决方案3】:

    它可以使用 LINQ 来完成,但这仅在您想要(接受)数组数组 int[][] 而不是直接的二维 int[,] 时才实用。

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

    【讨论】:

    • 这就是所谓的“锯齿状”数组吗?
    • 是的,但我更喜欢数组数组
    • PS:我不确定所有这些(ReadLines)是否在 XNA 中可用。错过了那个标签。
    • 我认为有Readline() 会一一完成。不过我还没有遇到过复数版本。
    • 还有System.IO.File.ReadAllLines() ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多