Laden...

Arbeiten mit Dateien

Letzter Beitrag vor 19 Jahren 32 Posts 7.096 Views
Arbeiten mit Dateien

Ich habe die frage schon in einem anderen Forum gestellt doch da bekomme ich keine Antwort deswegen frage ich hier nochmal

Ich habe folgendes Problem:
Zwei Datein in der einen Stehen (orte.txt) die Orte mit ID
1|Berlin
2|Köln
3|Duisburg
usw
In der anderen (name.txt) stehen Namen und auch die ID der Orte
NameID|Name|OrtID
1|Fritz Meier|1
2|Fritz_Meier|3
3|Fritz-Meier|2

Ich will nun wenn das Programm startet alle Orte in einer Liste angezeigt werden
Was soweit auch kein Problem ist nur wenn ich jetzt auf ein Ort klicke soll sich eine weitere Liste öffen in der alle IDs und Namen aus name.txt von dem ausgewählten Ort stehen

Das war soweit geklärt

Aber ich habe immer noch ein Problem
Ich lade über ein MenüItem die Datei

public void menuItem2_Click(object sender, System.EventArgs e) 
      { 
          
         FileStream f; 
         StreamReader r; 
         openFileDialog1.FileName="DYN_team"; 
         openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ; 
         openFileDialog1.RestoreDirectory = true ; 
         String line; 
         if(openFileDialog1.ShowDialog()== DialogResult.OK) 
         { 
            f = new FileStream(openFileDialog1.FileName, FileMode.Open); 
            r = new StreamReader(f); 
            while ((line = r.ReadLine()) != null) 
            { 
               usr = line.Split('|'); 
               //if (usr[5] == "1") 
               //{ 
               listBox1.Items.AddRange(new object[] {usr[4]}); 
                
               int auswahl=listBox1.SelectedIndex; 
               String auswahl2==listBox1.SelectedItem.ToString(); 
               if((auswahl2==usr[4])) 
               { 
                  listBox2.Items.AddRange(new object[] {usr[1]}); 
                   
               } 
          
               //} 
            } 
            r.Close(); 
             
             
         } 
      } 

Ich habe zum Testen nun eine 2.ListBox gemacht in der dann die ID des Ortes ausgegeben wird von dem ausgewählten Ort
Nur leider gibt es da Probleme mit dem auswahl2==listBox1.SelectedItem.ToString();
Das kann man wohl nur in der public void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) Methode machen

Aber ich kann die Werte der Varibalen nicht von einer Methode in die andere übernehmen

Ich komme da einfach nicht weiter

Original von alf468
Nur leider gibt es da Probleme mit dem auswahl2==listBox1.SelectedItem.ToString();

Was gibt es denn da für Probleme? In jedem Fall solltest du die Abfrage aus der while-Schleife rausziehen und dazu prüfen ob überhaupt etwas selektiert ist.

//if (usr[5] == "1")
//{
listBox1.Items.AddRange(new object[] {usr[4]});

Der Code kommt mir sehr suspekt vor. Du fügst beim Laden der Namen-ListBox Elemente zur Orte-ListBox hinzu?

Gruss
Pulpapex

Das ist das Problem:

Nur leider gibt es da Probleme mit dem auswahl2==listBox1.SelectedItem.ToString();
**Das kann man wohl nur in der public void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) Methode machen **
Aber ich kann die Werte der Varibalen nicht von einer Methode in die andere übernehmen

Ich lade die Orte aus der der Datei DYN_team

listBox1.Items.AddRange(new object[] {usr[4]}); 

Werden alle im Array an 4.Stelle stehen daten in die listbox gelesen
Das sind die Namen der Orte
Nun wählt der User den Ort aus und klickt auf ein OK Button
Es öffnet sich ein neues Fenster wo alle Einwohner der ausgewälten Ortes stehen

Dazu habe ich gedacht von dem ausgewählten Ort die ID die auszulesen

String auswahl2==listBox1.SelectedItem.ToString(); 
               if(auswahl2==usr[4]) 
               { 
                  listBox2.Items.AddRange(new object[] {usr[1]}); 
                   
               } 

Im String auswahl2 soll der Name des ausgewählten Ortes steht
Wenn dieser gleich eines Ortsnamen aus der Texdatei ist dann soll erstmal zum Test die OrtsID in einer 2.Listbox ausgegeben werden

Das ist kein Problem, das ist ein Workaround für ein Problem, dessen Ursache du noch nicht gefunden hast. Ich weiss jedoch noch nicht mal wie sich das Problem äußert. Wird in der Zeile z.B. eine NullReferenceException ausgelöst oder was passiert da?

Nochmal zu dem Code:
Du sagst der lädt die Orte in listBox1.

listBox1.Items.AddRange(new object[] {usr[4]});

Gleichzeitig soll aber schon ein Eintrag in listBox1 selektiert sein.

String auswahl2==listBox1.SelectedItem.ToString(); // (da ist ein '=' zu viel.)

Das passt doch irgendwie nicht zusammen. Irgendwie fehlt dieser Teil:

Nun wählt der User den Ort aus und klickt auf ein OK Button

Die Fehlermeldung ist:

Eine nicht behandelte Ausnahme des Typs 'System.NullReferenceException' ist in WindowsApplication2.exe aufgetreten.

private void button1_Click(object sender, System.EventArgs e)
		{
			Form2 test=new Form2();
			test.ShowDialog();
			String auswahl2=listBox1.SelectedItem.ToString(); 
			if((auswahl2==usr[4])) 
			{
				listBox2.Items.AddRange(new object[] {usr[4]});
						
			}
		}

War ein kleiner Denkfehler mit dem SelectedItem X(

X( X( kann mir hier auch keiner helfen??

Hallo alf468,

eine System.NullReferenceException ist von Ferne immer schwer zu diagnostizieren, weil es ja quasi jede beliebige Variable sein kann, die bei der Benutzung null ist. Dagegen sollte es für dich relativ leicht sein, weil es sich ja um eine sehr klar definierte Fehlersituation handelt. Ein Debugger - oder zumindest der Stacktrace in der Exception - sollte ein Übriges tun, um den die Fehlerstelle zu lokalisieren.

HTH

herbivore

Es kommt jetzt kein Fehler mehr aber es läuft nicht so wie ich es will

String auswahl2=listBox1.SelectedItem.ToString(); 
			if((auswahl2==usr[4])) 
			{
				listBox2.Items.AddRange(new object[] {usr[4]});
						
			}

Das Problemist das auswahl2 nicht ==usr[4] weil die Werte aus der Menü-Methode nicht übernommen werden
Wie bekomme ich das den hin??

Äh Leute so schwer kann das doch nicht sein ⚠

Hallo alf468,

äh, alf468, so schwer kann das doch nicht sein. Hast du dir denn schon mal - per Debugger oder MessageBox - angeschaut, was für Werte in auswahl2 bzw. usr[4] drinstehen? Wenn es wirklich an der if-Abfrage liegt, dann sollte es wirklich nicht schwer sein, die Ursache zu finden - zumindest wenn man das ausführbare Programm parat hat. Von Ferne ist es um einiges schwerer.

HTH

herbivore

Habe das ganz nochmal überprüft
Wenn ich das Array usr ausserhalb der while Schleife aufrufe steht da nur die letzte Zeile drin X(

Warum ist mir auch klar aber ich will ja alle Namen in anderen Methode haben 🤔

Hallo alf468,

mir ist noch aufgefallen, dass du im Zusamenhang mit usr[4] von Daten, die "im Array an 4. Stelle stehen", sprichst. Da Arrays bei Index 0 beginnen, ist usr[4] aber das Datum, das an fünfter Stelle steht.

Außerdem haben deine Beispieldateien maximal drei Teile, also meinst du vielleicht eher Daten, die im Array an dritter Stelle stehen. Das wäre dann usr[2].

HTH

herbivore

Das ist mir gleich zu Anfang aufgefallen. Die Beschreibung passt nicht zum Code und am Code ist nicht zu erkennen was er darstellen soll - weil Code in Ereignishandler geschrieben wird und weil wirklich alle Bezeichner nichtssagend sind.

Also bevor es sich überhaupt lohnt da nochmal drüber zu schauen, sollte ne aktuelle Version erstmal leserlich mit Kommentaren gepostet werden - wo Code und textuelle Beschreibung auch zusammenpassen.

Das war nur ein Beispiel aber egal ich habe das Programm jetzt auf das Beispiel angepast.

Und ich muss mich damit bei euch bedanken 😁
Jetzt geht alles so wie ich es will 👍

Über das Menü wird die Datei geladen

private void menuItem2_Click(object sender, System.EventArgs e)
		{
			FileStream f;
			openFileDialog1.FileName="Ort";
			openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
			openFileDialog1.RestoreDirectory = true ;
			String line;
			if(openFileDialog1.ShowDialog()== DialogResult.OK)
			{
				f = new FileStream(openFileDialog1.FileName, FileMode.Open);
				r = new StreamReader(f);
				while ((line = r.ReadLine()) != null) 
				{
					usr = line.Split('|');
					listBox1.Items.AddRange(new object[] {usr[1]});
					int auswahl=listBox1.SelectedIndex;
					
				}
				
				r.Close();
				
				pfad=openFileDialog1.FileName;
				
				
			}
		}

Per OK Button wird die ID des Ortes "geholt"

private void button1_Click(object sender, System.EventArgs e)
		{
			FileStream f;
			String line;
			String a=listBox1.SelectedItem.ToString();
			
			f = new FileStream(pfad, FileMode.Open);
			r = new StreamReader(f);
			while ((line = r.ReadLine()) != null) 
			{
				usr = line.Split('|');
				if((a==usr[1])) 
				{
					listBox2.Items.AddRange(new object[] {usr[0]});
						
				}
			}
			f.Close();

EDIT:Eine Frage ich aber noch 🙂
Wie kann ich bestimmte Orte aus der ListBox rausfiltern also das sie nicht mit angezeigt werden?

Hallo alf468,

ich würde die Negativliste als Hashtable speichern, wenn du die Namen direkt hast z.B. so:


Hashtable htFilter= new Hashtable ();
htFilter["Berlin"] = true;
htFilter["Hamburg"] = true;
htFilter["München"] = true;

Wenn die Namen in einer Datei stehen, musst du die natürlich erst einlesen.

Dann reicht vor dem


listBox1.Items.AddRange(new object[] {usr[1]});

was man übrigens auch als


listBox1.Items.Add(usr[1]);

schreiben könnte, ein


if (!htFilter.Contains (usr[1])) {

HTH

herbivore

Also ich mache erst mal

Hashtable htFilter= new Hashtable();

Dann schreibe ich vor dem

listBox1.Items.Add(usr[1]); 
if (!htFilter.Contains (usr[1])) 

Aber wie lege ich die zu streichenden Orte fest?

Hallo alf468,

hm, wunder, das steht doch schon oben.

Wenn du einen Ort, den du streichen willst, hast, wobei mal egal sein so, ob als Literal wie "Berlin" oder als Variable wie strOrt, wobei die Variable strOrt womöglich jeweils innerhalb einer Schleife, die eine Datei einliest, gesetzt wird, auf jeden Fall, musst du nach dem Erzeugen der Hashtable diesen (jeweiligen) Ort als Schlüsel hinzufügen, also entweder


htFilter["Berlin"] = true;
// oder
htFilter[strOrt] = true;

herbivore

Ok danke es geht 👍 👍

Man selectiert doch ein Item in der ComboBox doch mit
comboBox1.SelectedText="text"; oder??
Das geht nämlich nicht 🤔

Was mich auch wundert ist das kein Ü, Ä oder so vorhanden ist 🙄

Damit ich jetzt zum Ende komme meine Abschlussfrage 🙂
Ich habe es jetzt so gemacht das man auch den Namen eines Einwohners ändern kann.
Also habe ich drei Forms (Ort,Einwohner und Einwohner ändern)
Auf dem Form Einwohner ändern habe ich jetzt ein Button wenn man da drauf klickt soll das ganze dann in name.txt gespeichert werden.

private void button1_Click(object sender, System.EventArgs e)
		{
			FileStream f;
			String line;
			String[] usr;
			f = new FileStream(pfad2, FileMode.Open); //Den Dateipfad wird aus der ersten Form bezogen
			StreamReader r = new StreamReader(f);
			while ((line = r.ReadLine()) != null) 
			{
				usr = line.Split('|');
				if((id==usr[0])) //Wenn NameID (aus Form2) gleich der ID in der txt
				{
					
					usr[3]=textBox1.Text; //an Stelle 4 steht der Name 
					
					
					TextWriter stringWriter = new StringWriter();
					using(TextWriter streamWriter = 
							  new StreamWriter(pfad2))
					{
						stringWriter.WriteLine(usr[3]);
						stringWriter.Close();
						streamWriter.Close();
					}

						
				}
			}
			f.Close();
			r.Close();		
		}

Das ganze geht nicht da ja noch aus der Datei gelesen wird .
Aber wie soll ich das den sonst machen?

Och kommt jetzt gibt mir noch den letzten Tip X(

Warum wird denn noch aus der Datei gelesen, wo doch beim Klick auf den Button gespeichert werden soll?

Ich lasse den Namen in einem TextFeld anzeigen wo dann der User den Namen ändern kann.
Per klick auf den Button wird die änderung gespeichert

Hallo alf468,

das beantwortet m.E. nicht die Frage. Zu dem Zeitpunkt an dem der Benutzer den Namen wählt, sind die Listboxen schon gefüllt und das Lesen abgeschlossen - zumindest sollte das so sein, oder?. Warum ist zu diesem Zeitpunkt die Datei noch offen?

Oder anders herum: Wenn du die Datei rechtzeitig schließt, dann solltest du sie auch zum Schreiben wieder öffnen können.

herbivore

Es soll ja nur der ausgewählte Name geändert werden

if((id==usr[0])) //Wenn NameID (aus Form2) gleich der ID in der txt
				{usr[3]=textBox1.Text; //an Stelle 4 steht der Name 
TextWriter stringWriter = new StringWriter();
					using(TextWriter streamWriter = 
							  new StreamWriter(pfad2))
					{
						stringWriter.WriteLine(usr[3]);
						stringWriter.Close();
						streamWriter.Close();
					}

						
				}

So muss das Speichern doch in Lesen rein!?
Nur so wird doch der ausgewählte Namre gändert

Hallo alf468,

wenn du in einer Text-Datei eine Änderung vornehmen will, die die Länge der Datei beeinflusst (der neue Name hat ja potentiell eine andere Länge), muss man in der Regel die Datei als ganzes neu schreiben.

Ich würde das klar trennen:

  1. Schritt: Datei wird in Listbox gelesen; Datei schließen.
  2. Schritt: Name wird (per Dialog) in der Listbox geändert.
  3. Schritt: Inhalt der geänderten ListBox wird in die Datei zurückgeschrieben; Datei dazu neu öffen und von Anfang an schreiben.

HTH

herbivore

In der ListBox stehen aber nur die Namen
Was ich ändern will sind aber auch noch Adresse,Alter,Beruf ..
Deswegen ja auch ein neuer Dialog mit den Textfeldern 😉
Die ID vom Namen wird zB nicht geändert

Hallo alf468,

ich denke du kommst um das neu Schreiben der Datei - zumindest ab der Position der Änderung - nicht herum. Es gibt leider keinen Anpruch darauf, dass es für alle Programmierprobleme eine elegante Lösung gibt. Im Detail gibt es natürlich diverse Varianten, dieses neu Schreiben zu realisieren.

herbivore

zumindest ab der Position der Änderung

Wie soll ich das den machen??
Es wäre nett wenn du ein Beispiel geben könntest

Hallo alf468,

ich würde es in den drei Schritten machen, wie oben beschrieben. Wenn zusätzliche Informationen zu berücksichtigen sind, muss man die sich halt irgendwo merken.

herbivore

Es geht nun alles 😁
Aber nun noch eine Frage 😁
Kann man das .NET Framework (also die benötigten Komponenten) irgendwie im Setup mit einpacken so das der User nix runterladen muss auch das NET nicht instalieren muss??

28,7MB 8o
Ich glaube ich werde das ganze mal in C++ umschreiben 😁
Ist ja auch ne schöne Übung 👍