2012-03-12 21 views
3

これで、.txtファイルを読み込むことができました...今、私はこの情報を2D配列に変換する最良の方法を見つけようとしています。txtファイルから2D配列を作成

私のテキストファイル(最初の二つの数は、高さと幅を提供):

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

は、今私は次何をする必要があるか2のサイズを定義していますディメンションマップ配列を作成し、エントリ値を設定します。これはちょっと立ち往生し、データをループするさまざまな方法を見つけましたが、いずれも非常にきれいだったとは思いません。

私がやったことは、改行で分割されたループが1つあり、コンマ区切りで分割された別のループがあることです。

これを行うにはこれが最善の方法ですか、それとも良い方法がありますか?

5 
5 

が、私はそれをこのように好むだろうが、結果として、以下のコードは、ファイルを2回読み取ります

+0

あなたは正しいトラックのようです。おそらくToArray()などの拡張メソッドを使用しようとします。 – Tom

+0

@JohnSaunders申し訳ありませんが、私の間違いです。 – diggersworld

答えて

0

以下のコードは、あなたのサンプルの.CSVファイル内の行への最初のを必要としません。サンプルの最初の2つの行を少し変更して使用します。

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

それは少し長いように見えます...私の解決策をチェックしてください。 – diggersworld

+0

はい、私が言及した変更を行いました。最初の2行に高さと幅を置くと、2番目の機能が不要になります。しかし、私はあなたの方法で入力ファイルの形式が嫌いです。 *それは好みのものです* – JohnB

+0

Mmmm ...理解できます...一度大きくなると列の数などを数えにくくなります...自動化が役立つでしょう。 – diggersworld

0

これは私が思いついた解決策です。

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

それはLINQで行うことができますが、あなたは、アレイのアレイ、int[][]代わりにストレート2次元int[,]のを(受け入れる)したいときには、唯一の実用的です。

+0

これは「ギザギザ」アレイと呼ばれていますか? – diggersworld

+0

はい、しかし配列の_配列が好ましいです –

+0

PS:このすべての(ReadLines)がXNAで利用可能かどうかはわかりません。そのタグを逃した。 –

関連する問題