Autor Beitrag
Stephan202
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mo 11.07.11 22:43 
Hallo,

habe einen Code, der aus einer txt-Datei ein Array machen soll. Das Ganze lief soweit für
2 Spalten und beliebig viele Zeilen. Nun habe ich versucht, das ganze für beliebig viele Spalten umzuprogrammieren.
Das Compilieren funktioniert, nicht aber das Ausführen des Codes.

Hier ist die Funktion, die die Datei ausliest:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
public string[,] tabelle(string pfad, string trennzeichen)
    {
      //initialisieren
      string[,] table={{"",""},{"",""}};
      
      try
        {
                  
          string[] fileContent = File.ReadAllLines(pfad);
          int linecount=fileContent.GetLength(0);
          
          //table = new string[linecount, 2];
          
          
          string zeile;
          
          for (int i = 0; i < linecount; i++) 
          {
            zeile=fileContent[i];
            
            string[] datensatz=Regex.Split(zeile, trennzeichen);
//            table[i,0]=datensatz[0];
//            table[i,1]=datensatz[1];
            int j =0;
            foreach (string wort in datensatz)
            {
              table[i,j]=datensatz[j]; //Datenmatrix erstellen
              j=j+1;Print(table[i,j]);
            }
          }
        }
      catch (System.Exception excep)
        {
          MessageBox.Show(excep.Message);  
        }
        
      return table;
    }


Irgendwie werden die Daten damit nicht korrekt ausgelesen.
Wer kann helfen?

Vielen Dank schon im Vorraus!

Moderiert von user profile iconKha: C#-Tags hinzugefügt
Flitzs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 123
Erhaltene Danke: 7

Win7 x64/86 WinServer 2008 R2 x64
C#/C++/C VS2010
BeitragVerfasst: Mo 11.07.11 23:04 
Hallo!
Schau dir mal die Zeilen 4 und 28 genauer an.

Kürzer bzw. eleganter geht das übriges mit LINQ:
ausblenden C#-Quelltext
1:
2:
3:
 var table = from line in File.ReadAllLines("<Pfad>")
                       select from wort in line.Split('<Trennzeichen>')
                              select wort;


lg Flitzs
Stephan202 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Di 12.07.11 20:06 
Hi,

weiss trotzdem nicht, was man bei meinem Script ändern muss, damit es läuft.
Das es was mit der Indizierung/Dimensionierung zu tun hat, dachte ich mir schon.

Würden Deine 3 Codezeilen den gesamten Code meinerseits ersetzen und
aus einer mehrzeligen textdatei mit mehreren Spalten, separiert durch ein Trennzeichen,
ein 2D-Array einlesen oder ist das nur ein Fragment?
Flitzs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 123
Erhaltene Danke: 7

Win7 x64/86 WinServer 2008 R2 x64
C#/C++/C VS2010
BeitragVerfasst: Di 12.07.11 21:47 
Das Problem mit Array ist, dass sie was ihre Größe angeht, konstant sind.

user profile iconStephan202 hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden C#-Quelltext
1:
2:
//initialisieren
string[,] table={{"",""},{"",""}};



Du legst hier ein 2*2 Array an. Somit kannst du auch nicht mehr als 2 Zeilen mit jeweils 2 Wörtern einlesen. Du müsstest also zuerst ermitteln, wie viele Zeilen/Wörter du benötigst (sofern die Anzahl nicht immer gleich ist) und dann entsprechend das Array so dimensionieren, dass die Daten Platz haben.

Übrigens kann man ein leeres Array auch mit
ausblenden C#-Quelltext
1:
string[,] table = new string[2,2];					

erzeugen.

user profile iconStephan202 hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden C#-Quelltext
1:
j=j+1;Print(table[i,j]);					



Du erhöhst zuerst j um 1 (Inkrementierungen um 1 kannst du übriges auch mit dem ++-Operator durchführen) und greifst dann auf den j-ten Index im Array zu. Dieser ist aber ja noch nicht belegt, also zuerst Print dann Inkrementieren.

Meine 3 Zeilen ersetzen deinen gesamten Code, abgesehen von der Fehlerbehandlung, Print und der Funktionsdefinition/Return. Allerdings gibt er ein string[][] anstatt einem string[,] zurück. Wenn du unbedingt ein mehrdimensionales Array verwenden möchtest, musst du eben den oben beschriebenen Weg nehmen. Außerdem verwende ich Listen, da ihre Größe flexibel ist und daher das Problem wie bei den Arrays nicht auftritt. Wenn du aber unbedingt mit Arrays arbeiten möchtest, kann du die Listen auch in Array konvertieren (.ToArray())

lg Flitzs
Stephan202 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mi 13.07.11 00:10 
Danke für die Infos.

Warum funktioniert eigentlich Zeile 9 und 21 in meinem vorherigen Codestück, wenn Arrays immer dimensioniert werden müssen?

Ich hab den Code jetzt geändert und vor der Dimensionierung von table die Ermittlung der korrekten Spaltenzahl eingebaut.
Nun kann ich zwar via Print die Werte anzeigen, aber die Weiterverarbeitung der eingelesenen Tabelle wirft einen
Indexfehler. Ich versteh nicht warum. Es ist doch nach wie vor ein m*n Array?
Vorher war der Code für fixe 2 Datenspalten geschrieben, da hats noch funktioniert mit der Weiterverarbeitung.
Das eingelesenen Text-File ist jeweils das Gleiche. Hier der aktuelle Code:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
public string[,] tabelle(string pfad, string trennzeichen)
{
  //initialisieren
  string[,] table={{"",""},{"",""}};
  
  try
  {
    string[] fileContent = File.ReadAllLines(pfad);
    int linecount=fileContent.GetLength(0);
    //Spaltenzahl bestimmen
    string[] datensatz=Regex.Split(fileContent[0], trennzeichen);
    int rowcount=0;
    foreach (string wort in datensatz)
    {rowcount++;}
    //table = new string[linecount, 2];
          
    //table dimensionieren
    table = new string[linecount,rowcount];
          
    string zeile;
          
    for (int i = 0; i < linecount; i++) 
    {
      zeile=fileContent[i];
      datensatz=Regex.Split(zeile, trennzeichen);
//      table[i,0]=datensatz[0];
//      table[i,1]=datensatz[1];
      int j =0;
      foreach (string wort in datensatz)
      {
        table[i,j]=datensatz[j];//Print(table[i,j]); //Datenmatrix erstellen
        j=j+1;
      }
    }
  }
  catch (System.Exception excep)
  {
    MessageBox.Show(excep.Message);  
  }
        
  return table;
}


Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 13.07.11 09:38 
Hallo Stephan,

bei den Methoden File.ReadAllLines und Regex.Split übernehmen diese selber die Erzeugung (und passende Dimensionierung) des String-Arrays. Als Anwender dieser Methode verarbeitet man ja nur den Rückgabewert.

Wenn man aber selber ein Array erzeugt, so muß man eben im voraus die passende Dimension(en) angeben ehe man mittels des Index-Operators Daten dort hineinspeichern kann.

Flexibler geht es mit einer List<string> (aus System.Collections.Generic) da diese sich intern bei Bedarf selbständig vergrößert:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
List<string> list = new List<string>(); // keine Größenangabe nötig

for(int i=0; i<10; i++)
  list.Add("Hallo");
// list ist nun mit 10 Elementen gefüllt

Und 2-dimensionale Listen sind ebenfalls möglich: List<List<string>>.
Dabei muß man nur beachten (ähnlich wie bei String[][]), daß man für die Unterlisten ebenfalls Speicher anfordern muß:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
List<List<string>> list2 = new List<List<string>>(); // keine Größenangabe nötig

for(int i=0; i<10; i++)
{
  List<string> list = new List<string>(); // Unterliste erzeugen
  for(int j=0; j<5; j++)
    list.Add("Hallo");

  list2.Add(list); // Unterliste hinzufügen

Nun enthält list2 10 Unterlisten mit jeweils 5 String-Elementen (wobei jede Unterliste auch verschieden viele Elemente enthalten könnte).
Stephan202 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mi 13.07.11 20:01 
Danke für die Erklärungen.
Die Lists waren mir im Groben schon bekannt,
im vorliegenden Beispiel war es im definiert zweispaltigen Datensatz
kein Problem, die Arrays vorzudimensionieren.
Da der Code eine Funktion ist, die in weiteren Programmen verwendet wird,
will ich wohl auch weiterhin am Ende ein Array ausgeben.

Allerdings weiss ich noch nicht, warum der zuletzt gepostete Code noch nicht funktioniert,
wenn ich ihn als Unterfunktion in anderen Scripts nutze, wo die vorherige Version problemlos lief.
Ist da noch irgend ein Fehler drin? Ich kann keinen finden.
Flitzs
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 123
Erhaltene Danke: 7

Win7 x64/86 WinServer 2008 R2 x64
C#/C++/C VS2010
BeitragVerfasst: Mi 13.07.11 20:33 
Hallo!
Die Fehlerbeschreibung "funktioniert nicht" ist i.d.R. schlecht ;)

Das einzige mögliche Problem (abgesehen von einigen Schönheitsmakeln und unnötigen Schleifen/Variablen usw.) das mir bei deinem Code von vor drei Posts aufgefallen ist, dass du die Anzahl der Wörter auf Basis der ersten Zeile ermittelst. Wenn jedoch eine der nachfolgenden Zeilen mehr Wörter hat, funktioniert es dann natürlich nicht mehr. Kann das der Fall sein?

Ich gehe natürlich davon aus, dass das Format der Datei passt (Trennzeichen an der richtigen Stelle usw.).

lg Flitzs
Stephan202 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 16



BeitragVerfasst: Mi 13.07.11 21:16 
Hallo,

Nachdem ich den Rechner gestern ausgeschaltet und heute wieder hochgefahren habe lief das Ding wieder.
Hm. Scheint also nicht am Code gelegen zu haben.
Vielen Dank nochmal Euch allen für die gute Hilfe.
Werd mir Eure hilfreichen Kommentare in mein persönl. "C# für Teilzeit-Amateure"-Handbuch kopieren. :-)