Autor Beitrag
interessierter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Sa 02.06.12 15:04 
Hallo Zusammen

Ich habe eine Frage zum Dateihandling. Dazu habe ich auch wieder einen Übungscode geschrieben.

Mein Code jetzt:

- Fragt ob mein eine neue Datei anlegen möchte, oder eine bestehende Datei laden

Falls neue Datei anlegen:

- Fragt Anzahl und Namen der Athleten ab und speichert es in Array
- Fragt nach Anzahl gemachter Klimmzüge und speichert Wert in Array
- Gibt aus wiviele Klimmzüge jeder Athlet geschafft hat
- Erstellt eine Datei mit allen Athleten und Anzahl Klimmzüge/Athlet

Bis hier klappt alles.

Wenn ich nun die Datei laden will, so das ich zu jedem Athlet die neue Anzahl Klimmzüge addieren kann und wieder in eine Datei speichern will habe ich ein Problem.

Die Frage:
Wie ist der Ablauf? Ich stelle es mir folgendermassen vor:

1. Datei auslesen
2. Inhalt der Datei sortieren nach Namen und Punktzahlen und wieder in ein Array speichern
3. Neue Anzahl Klimmzüge abfragen
4. Gesamttotal Klimmzüge/Athlet in die bestehende Datei schreiben

Liege ich so richtig? Bitte gebt mir ein paar Lösungsansätze.

Hier der 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:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Willst du einen neuen Wettkampf anlegen oder einen Wettkampf laden? Waehle:\n1 fuer Neuen Wettkampf anlegen\n2 fuer Wettkampf laden");
            string AuswahlText = Console.ReadLine();
            int Auswahl = int.Parse(AuswahlText);
            if (Auswahl == 1)
            {
                Console.WriteLine("Anzahl Teilnehmer eingeben");
                string Anzahltext = Console.ReadLine();
                int TeilnehmerAnzahl = int.Parse(Anzahltext);
                string[] Namen = new string[TeilnehmerAnzahl];
                Console.WriteLine("Namen der Teilnehmer eingeben");
                for (int i = 0; i < Namen.Length; i++)
                {
                    Namen[i] = Console.ReadLine();
                }
                int[] Punktzahl = new int[Namen.Length];
                for (int nr = 0; nr < Namen.Length; nr++)
                {
                    Console.WriteLine("Wieviele Klimmzuege hat " + Namen[nr] + " geschafft?");
                    string AnzahlText = Console.ReadLine();
                    int Anzahl = int.Parse(AnzahlText);
                    int x = 0;
                    x = Anzahl;
                    Punktzahl[nr] += x;
                }
                for (int nr = 0; nr < Namen.Length; nr++)
                {
                    Console.WriteLine(Namen[nr] + " hat " + Punktzahl[nr] + " Klimmzuege geschafft");
                }
                Console.WriteLine("Willst du diesen Stand speichern? Waehle\n1 fuer Ja\n2 fuer Nein");
                string SpeichernText = Console.ReadLine();
                int SpeichernAbfrage = int.Parse(SpeichernText);
                if (SpeichernAbfrage == 1)
                {
                    Console.WriteLine("Dateiname eingeben");
                    string Pfad = "C:/Users/daniele/desktop/" + Console.ReadLine();
                    var Dat = new StreamWriter(Pfad);
                    for (int nr = 0; nr < Namen.Length; nr++)
                    {
                        Dat.WriteLine(Namen[nr]);
                        Dat.WriteLine(Punktzahl[nr]);
                    }
                    Dat.Close();
                }
                if (SpeichernAbfrage == 2)
                {
                    Console.WriteLine("Das Programm wird beendet. Die Daten wurden nicht gespeichert");
                }
            }
            if (Auswahl == 2)
            {
                Console.WriteLine("Dateiname eingeben");
                string Pfad = "C:/Users/daniele/desktop/" + Console.ReadLine();
                var x = new StreamReader(Pfad);
            }
        }
    }
}


Grüsse
interessierter
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 02.06.12 15:51 
Hallo interessierter

Um die Daten des Spielstandes speichern zu können, bietet sich am besten an, eine Klasse zu erstellen, die dann die entsprechenden Daten beinhaltet.
Wie du die Daten dann speicherst, ist im Grunde ziemlich egal, das hängt davon ab, wie du das machst.
Aber du musst dir dabei auch überlegen, wie du alle möglichen Werte eindeutig in der Datei fest legen kannst und da liegt dann auch das Problem. Deswegen würde ich anbieten, die Daten mittels xml zu serialisieren. Dann geht das ganz einfach.

Wie das geht lässt sich mit Hilfe von Google ganz leicht raus finden. Gibts sogar fertig geschriebene Methoden, die lesen und schreiben können.


Ach und noch zwei Hinweise:

Also ich würde die Konvertierung der Eingabe, die du ja mit Parse gelöst hast, mit der TryParse-Methode erledigen. Das gibt dem Programm eine gewisse Sicherheitund lässt Fehler gleich am Kern abfangen und lösen.

Zum Schluss lässt du ja noch eine Ausgabe geben und das Programm gleich beenden. Die Ausgabe wird aber niemand sehen können, deshalb noch die Sleep-Methode, die das dann z.B. für eine Sekunde anhalten kann.
interessierter Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Sa 02.06.12 16:09 
Vielen Dank für die Inputs.

Das mit tryparse ist mir bekannt. Auch wie ich z.B. Methoden verwenden kann, um falsche Eingaben von Anfang an auszuschliessen.

Das Problem ist, das ich das Thema Klassen bisher noch nicht besprochen habe mit meinem Coach. Wir sind jetzt erst mal bei den Grundlagen des Dateihandlings angekommen. Klassen ist bald ein Thema. Dann werde ich diese auch verwenden.

Bei dieser Übungsaufgabe muss ich mich mit den mir bekannten Mittel durchschlagen. Das wäre:

- StreamWriter
- StreamReader
- Eindimensionale Arrays
- if,while, for Anweiungen

Bei jeder neuen Aufgabenstellung wähle ich zuest immer die einfachste Variante. Wenn ich es dann gelöst habe, ergibt sich für mich gleich eine zweite Aufgabe, wo ich den bestehenden Code dann vereinfache und leserlicher gestalte.

Nehmen wir jetzt mal meinen bestehenden Code als Grundlage. Welche Werkzeuge brauche ich ab dem "Daeti lesen" noch um die Übung zu beenden? Meiner Meinugn nach sollte es ja gehen, auch wenn es nicht die beste Variante ist. Immerhin kann ich dann den Ablauf analysieren.

Ist mein Code Grundlegend falsch oder kann ich auf diesem Wege mein Ziel erreichen?

Meine letzte Codezeile liest ja die Datei aus. Ab da weiss ich nicht mehr wie weiter. habs schon mit ReadtoEnd versucht. Wie gebe ich nach dem Auslesen der Datei die Namen mit deren aktuellen Anzahl Klimmzüge aus?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 02.06.12 16:17 
Hallo,

so wie du die Daten mittels WriteLine abgespeichert hast, so kannst du diese entsprechend mit ReadLine wieder zeilenweise einlesen.

Zur eigenen Übersicht würde ich dir aber raten (auch wenn du keine eigene Klasse dafür anlegen willst), deinen Code in Methoden auszulagern.
Und dein Coach sollte dir trotzdem zuerst die Grundlagen der Sprache C# (Klassen, Methoden, Eigenschaften, Ereignisse, ...) beibringen, bevor explizit auf einzelne .NET-Klassen (wie die für das Datei-Handling) eingegangen wird.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 02.06.12 17:48 
Dass ihr Datei-Handling vor Klassen besprecht, finde ich aber auch sehr seltsam. O.o

Schließlich sind Klassen mit das Grundlegendste und ohne die kann man das ganze Prinzip der Objektorientierung komplett über den Haufen werfen. Sprich ihn mal darauf an, ob es nicht sinnvoller wäre, erst die Grundlagen zu klären.


Zum Problem:

Wie du die Datei schreibst, ist nicht schwer, das kannst du auch ohne uns. ^^

Um das Problem ohne Klassen zu lösen, musst du speziell mit dem Text arbeiten.
Wie Th69 schon sagte, kannst du Zeile für Zeile aus einer Datei lesen.
Wenn du, beim Speichern der Daten, vorher auch Zeile für Zeile geschrieben hast, dann lässt sich das auch relativ machen.

So würde ich in die Datei schreiben, dann lässt es sich auch leicht wieder aus lesen:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
AnzahlTeilnehmer,3
Heinz,20
Andreas,18
Sebastian,23
.
.
.


Das Prinzip ist ganz einfach.
Du musst dazu für jede Zeile heraus finden, an welcher Stelle das Komma (oder irgendein anderes Zeichen) steht.
Damit kannst du dann alles davor und alles danach ausgeben lassen.
Die erste Zeile beinhaltet die Anzahl Teilnehmer und in den nächsten Zeilen sind die Teilnehmer.
Der Text davor ist der Name und der Danach gibt die Anzahl Klimmzüge aus.

Wenn da noch mehr gespeichert werden soll, müsstest du das am Anfang der Datei machen, denn die Anzahl der Teilnehmer soll ja beliebig sein und wenn die am Schluss stehen, fällt das Auslesen am einfachsten aus.

Das erste Vorkommen eines bestimmten Zeichens kannst du mit der Methode IndexOf heraus finden, nämlich so:
ausblenden C#-Quelltext
1:
int index = Text.IndexOf(',');					

Und mit der Substring-Methode kannst du dann heraus finden, was davor und danach steht.
ausblenden C#-Quelltext
1:
2:
3:
string[] Ergebnisse = string[2];
Ergebnisse[0] = Text.Substring(0, index - 1);
Ergebnisse[1] = Text.Substring(index, Text.Length - 1);

Bei Substring musst du darauf achten, dass der PC immer Null-basierend zählt und ich die Beispiele oben nicht getestet habe. Bin mir also nicht sicher, ob das mit den Zahlen exakt hin haut. ^^

Auf diese Weise musst du dir dann Stück für Stück irgendwie die Daten aus der Datei lesen.
Es ist umständlich, aber eigentlich nicht schwer. Du musst bloß darauf achten, dass du im Programm dann Zeichen, wie hier im Beispiel das Komma, nicht zulässt, da es die Arbeit mit der Datei zerstören würde.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 02.06.12 18:04 
Hallo Palladin700,

das Schreiben hat er ja schon gecodet:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
var Dat = new StreamWriter(Pfad);
for (int nr = 0; nr < Namen.Length; nr++)
{
    Dat.WriteLine(Namen[nr]);
    Dat.WriteLine(Punktzahl[nr]);
}
Dat.Close();

Und daher sieht das Einlesen dann (fast) analog aus.

Einzig die TeilnehmerAnzahl sollte noch zusätzlich als erstes mitgespeichert werden, um daraus dann wieder beim Einlesen das Array dynamisch erzeugen zu können!
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 02.06.12 18:27 
Achso, ja das hab ich übersehen.

Ich würde es trotzdem so machen, wie ich beschrieben habe, das macht das Auslesen einfacher, weil alle Daten eines Spielers in eine Zeile kommen.


Bei seiner Variante ist das lesen aber auch nicht so unterschiedlich:
Einfach Zeile für Zeile auslesen, allerdings musst du wissen, in welcher Zeile was steht.

Auf msdn findet sich in einem Beispiel folgender Code-Ausschnitt:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
            using (StreamReader sr = new StreamReader(path)) 
            {
                while (sr.Peek() >= 0
                {
                    Console.WriteLine(sr.ReadLine());
                }
            }


Den using-Block würde ich hier jetzt nicht benutzen, aber das ist ja jedem frei gestellt.
Da du den noch nicht kennst, hier eine angepasste Variante:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
List<string> arr = new List<string>();
StreamReader sr = new StreamReader(path);
while (sr.Peek() >= 0
{
    arr.Add(sr.ReadLine());
}


List ist hier eine Klasse, die im Grunde das gleiche macht, wie ein Array, aber noch ein paar Zusätze bietet.
Eine List-Variable erstellst du so:
ausblenden C#-Quelltext
1:
List<DATENTYP> VARIABLENNAME = new List<DATENTYP>();					

Das ist dem Array sehr ähnlich:
ausblenden C#-Quelltext
1:
DATENTYP[] VARIABLENNAME = new DATENTYP[LÄNGE];					

Ein Unterschied ist der, dass bei der Liste keine feste Länge angegeben werden muss und dass es die Add-Methode gibt, die ein weiteres Element hinzu fügt.

Damit das aber funktioniert, musst folgende Zeile:
ausblenden C#-Quelltext
1:
using System.Collections.Generic;					

im Kopf des Quellcodes enthalten sein.

Danach kannst du arr wie ein dir bekanntes Array verarbeiten.
Wie du das machst, hängt dann davon ab, wie du alle Daten in die Datei legst.
interessierter Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: Sa 09.06.12 14:41 
Vielen Dank für die vielen Inputs. Ich werde mich zu gegebener Zeit auch mit diesen Themen befassen. Bei meiner jetzigen Übung will ich vorest aber nichts neues dazu nehmen und nur mit den mir bekannten Programmier-Werkzeugen die Aufgabe lösen. Mir ist völlig klar das es viel besser wäre die Abfragen in Methoden auszulagern. Das mache ich auch als weitere Übung, aber erst nachdem ich mein Problem mit den einfachsten Mitteln lösen konnte. Bisher habe ich noch jeden meines "1. Codes" nach Erledigung der Aufgabe weiter bearbeitet, und mit Funktionen etc. erweitert.

Abgesehen von allem was man besser oder anderst machen könnte, geht es bei meiner jetzigen Frage nur darum wie ich die ausgelesenen Daten meiner Datei weiterverarbeiten kann. Bitte gebt mir nur diesbezüglich weitere Lösungsansätze.

Mein aktueller Stand:
Ich lese eine Datei zeilenweise aus und gebe die Datei mittels Console.WriteLine aus. Die Datei sieht so aus:

oliver
10
paul
5

Meine Frage:
Ich will jetzt den aktuellen Stand der letzten Runde ausgeben was in der Konsole so aussehen müsste:

Oliver hat bisher 10 Klimmzüge geschafft
paul hat bisher 5 Klimmzüge geschafft.

Die aktuelle Anzahl an Klimmzügen/Teilnehmer will ich so speichern können, das ich nach der neuen Anzahl Klimmzüge fragen kann, und diese mit der alten Anzahl addieren kann. Ich weiss auch wie das geht. Ich weiss nur nicht wie ich den Inhalt meiner Arraydatei so auslesen kann, das ich gezielt ausgaben machen kann, und die darin enthaltenen Werte mit neuen Werten ergänzen kann.

Hier mein aktueller Code, wo ich die Datei zeilenweise auslese:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
           if (Auswahl == 2)
            {
                string Zeile;
                Console.WriteLine("Dateiname eingeben");
                string Pfad = "C:/Users/daniele/desktop/" + Console.ReadLine();
                var x = new StreamReader(Pfad);
                while ((Zeile = x.ReadLine()) != null)
                {
                    Console.WriteLine(Zeile);
                }
            }
        }
    }
}


Bitte gebt mir dazu eine Antwort. Soabald ich dann gesehen habe wie man grundlegen vorgeht um ein Array auszulesen und weiterzuverarbeiten, kann ich das analysieren und mit Methoden etc. erweitern.

Grüsse
interessierter
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 09.06.12 15:23 
Wie du alle Zeilen in ein Array bekommst, ist ganz einfach. Die Klasse File bietet dazu alles, was du brauchst:

ausblenden C#-Quelltext
1:
string[] lines = File.ReadAllLines(pfad);					


Wenn du mit Dateien oder Ordnern arbeitest, bietet sich allgemein immer an, erst einmal die Klassen Directory und File nach brauchbaren Methoden zu durchsuchen. Bei der Arbeit mit Datei-Pfaden gibt es die Klasse Path, die auch viele nützliche Methoden enthält.
Alle drei Klassen sind in dem Namespace System.IO, genau, wie die Sream-Klassen.

Wie du das dann machst, ist nicht weiter schwer.
Du kannst du foreach-Schleife nutzen, oder wenn du die Werte im Array direkt ändern willst, nimmst du die for-Schleife.


Wenn du aber mit StreamReader arbeiten sollst, wird es etwas komplizierter, aber auch nicht sehr:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
            // Der StreamReader, der die Datei liest
            StreamReader reader = new StreamReader(pfad);
            // Setzt den Stream auf die Position 0, damit der Reader auch wirklich am Datei-Anfang beginnt, zu lesen
            reader.BaseStream.Position = 0;

            // Eine Liste, die die Zeilen speichert. Ein Array ist ungünstig, weil ich da die Anzahl der Zeilen brauche.
            // Hier kann ich die Add-Methode nutzen und kann so ohne Kenntnis der Zeilen-Anzahl alle auslesen.
            List<string> Lines = new List<string>();
            // EndOfStream gibt an, ob der Reader am Ende der Datei angekommen ist.
            // Das Ausrufezeichen signalisiert, dass die Schleife laufen soll, solange der Reader NICHT am Ende der Datei ist.
            while (!reader.EndOfStream)
            {
                // Fügt der Liste die gelesene Zeile hinzu
                Lines.Add(reader.ReadLine());
            }


Die Kommentare müssten den Code ausreichend erklären, ansonsten frag einfach.



PS:
Diese Zeile:
ausblenden C#-Quelltext
1:
var x = new StreamReader(Pfad);					

ist nicht sonderlich praktisch. Besser ist, wenn du der Variable immer genau den Typ gibst, den sie auch hat, also StreamReader.
Außerdem sollten die Variablen einen selbst erklärenden Namen haben. Nenne die Variable doch einfach reader?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 09.06.12 15:56 
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden C#-Quelltext
1:
var x = new StreamReader(Pfad);					

ist nicht sonderlich praktisch. Besser ist, wenn du der Variable immer genau den Typ gibst, den sie auch hat, also StreamReader.

Die Variable hat damit genau diesen Typen ;-) Und Type Inference ist für mich so ziemlich das praktischste, was es gibt, weil ich damit nicht mehr redundanten Code schreiben muss.

Viel wichtiger erscheint mir, dass man sich die Nutzung der using-Klausel für Dinge angewöhnt, die nicht-gemanagte Systemressourcen verwenden. So wird in obigen Codes z.B. nicht die Close-Methode aufgerufen, was man bei Nutzung der using-Klausel gar nicht mehr vergessen kann.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 09.06.12 16:06 
Achso, ok, dann hab ich das wohl im Buch überlesen ^^
Wenn ich so drüber nach denke, ist das tatsächlich praktisch :D
Aber ich denke, ich werde das immer noch so machen, wie gehabt, einfach, weil ich mich dran gewöhnt habe.


Stimmt, dass using-Direktiven nutzt, ist wichtig.
Es stört einfach die Lesbarkeit.

Allerdings mache ich das manchmal auch so, wie er und zwar immer dann, wenn ich das nur ganz selten brauche. Also, wenn ich einmal ein Objekt von StreamReader instanziere, dann mache ich das so, aber auch nur, weil ich das dann später nicht brauche.
Oder wenn ich z.B. generische Methoden schreibe, die ich möglichst überall nutzen will. Dann soll das auch ohne zusätzliche Direktive funktionieren.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 09.06.12 16:32 
Was ist denn an
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
using(var x = new StreamReader(Pfad))
{
        while ((Zeile = x.ReadLine()) != null)
        {
          Console.WriteLine(Zeile);
        }
}

schlecht lesbar? :lupe:

Auch in einer generischen Methode solltest Du das Datei-Handle wieder freigeben. Dazu legst Du dann einfach fest, dass der Typ IDisposable implementieren musst und nutzt die using-Klausel.

Um es nochmal klar zu sagen: Wer seine Ressourcen nicht wieder freigibt, wenn er sie nicht mehr braucht, gehört virtuell gevierteilt :D

Ach ja, und die using-Klasuel enthält ja sogar noch einen try-finally-Block, sodass die Ressourcen sogar im Falle einer Exception noch korrekt freigegeben werden!

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 09.06.12 16:55 
Ich meine, dass sowas auf dauer nervt, wenn man einen Quell-Text lesen will:
ausblenden C#-Quelltext
1:
System.IO.StreamReader reader = new System.IO.StreamReader(pfad);					


Die Möglichkeit, die var bietet, finde ich tatsächlich praktisch, ich habe mich jetzt einfach nur daran gewöhnt, immer direkt den richtigen Typ anzugeben, daher werde ich das auch nicht ändern.



Und danke für die kurze using-Ausführung. Wusste zwar, was das ist, aber dass dort auch gleich die Dispose-Methode aufgerufen wird und ein Try-Finaly-Block vorhanden ist, das wusste ich nicht.
Werde das ab sofort öfters nutzen :D
Und ja, die Close-Methoden (rufen intern ja Dispose auf) habe ich einfach nur vergessen, mit einzubauen. Musst mich nicht vierteilen, ich mach nur grade nebenbei noch was^^
(Zur Info: Ich versuche schon eine Weile, eine Methode in der aktuellen Assambly nur mit Hilfe des Namens zu suchen. Wie ich den Namen erhalte, weiß ich schon, aber bei dem Rückweg wirds schwer. Ich glaub, ich probiere noch was rum und frag dann mal hier.)
interessierter Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 75



BeitragVerfasst: So 17.06.12 15:59 
Hallo Zusammen

Ich habe nun den Code so hingekriegt, das er tut was er soll. Ich lade die bestehende Datei, und addiere dann die neue Anzahl Klimmzüge mit der bestehenden Anzahl Klimmzüge/Teilnehmer. Somit ist meine 1. Aufagbe geschafft.

Nun will ich diesen Code vereinfachen mittels Methoden etc. Diesbezüglich habe ich mir ein paar Gedanken gemacht.

Meine neue Aufgabe:
Ich will nun den Code so umschreiben, das ich z.B. neue Diszipline (Liegestützen, Sit Ups etc.) jederzeit einfügen kann. Mit meinem jetzigen Code wäre sowas fast unmöglich, weil ich viele Wiederholungen drinn habe. Angenommen ich hätte 10 Teilnehmer und 15 Diszipline mit jeweils 3 Sätzen. Wenn ich dann eine neue Disziplin einbauen will, wird das praktisch unmöglich.

Ich habe mir folgendes überlegt:
1. Schreiben und Lesen einer Datei in eine Methode packen
2. Alle Abfragen bez. erreichter Anzahl in einer Disziplin auch in eine Methode packen

Wenn ich nun eine neue Disziplin einbauen willl, müsste ich ja nur die Methode erweitern welche nach der erreichten Anzahl fragt.

Bevor ich jetzt anfange, wie würdet Ihr den Code strukturieren? Was würdet Ihr in Methoden auslagern? Ich habe folgende Inhalte:

- Mehrere Teilnehmer
- Beliebige Anzahl an Disziplinen


Hier mein 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:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Willst du einen neuen Wettkampf anlegen oder einen Wettkampf laden? Waehle:\n1 fuer Neuen Wettkampf anlegen\n2 fuer Wettkampf laden");
            string AuswahlText = Console.ReadLine();
            int Auswahl = int.Parse(AuswahlText);
            if (Auswahl == 1)
            {
                Console.WriteLine("Anzahl Teilnehmer eingeben");
                string Anzahltext = Console.ReadLine();
                int TeilnehmerAnzahl = int.Parse(Anzahltext);
                string[] Namen = new string[TeilnehmerAnzahl];
                Console.WriteLine("Namen der Teilnehmer eingeben");
                for (int i = 0; i < Namen.Length; i++)
                {
                    Namen[i] = Console.ReadLine();
                }
                int[] Punktzahl = new int[Namen.Length];
                for (int nr = 0; nr < Namen.Length; nr++)
                {
                    Console.WriteLine("Wieviele Klimmzuege hat " + Namen[nr] + " geschafft?");
                    string AnzahlText = Console.ReadLine();
                    int Anzahl = int.Parse(AnzahlText);
                    int x = 0;
                    x = Anzahl;
                    Punktzahl[nr] += x;
                }
                for (int nr = 0; nr < Namen.Length; nr++)
                {
                    Console.WriteLine(Namen[nr] + " hat " + Punktzahl[nr] + " Klimmzuege geschafft");
                }
                Console.WriteLine("Willst du diesen Stand speichern? Waehle\n1 fuer Ja\n2 fuer Nein");
                string SpeichernText = Console.ReadLine();
                int SpeichernAbfrage = int.Parse(SpeichernText);
                if (SpeichernAbfrage == 1)
                {
                    Console.WriteLine("Dateiname eingeben");
                    string Pfad = "C:/Users/daniele/desktop/" + Console.ReadLine();
                    var Dat = new StreamWriter(Pfad);
                    for (int nr = 0; nr < Namen.Length; nr++)
                    {
                        Dat.WriteLine(Namen[nr]);
                        Dat.WriteLine(Punktzahl[nr]);
                    }
                    Dat.Close();
                }
                if (SpeichernAbfrage == 2)
                {
                    Console.WriteLine("Das Programm wird beendet. Die Daten wurden nicht gespeichert");
                }
            }
            if (Auswahl == 2)
            {
                Console.WriteLine("Dateiname eingeben");
                string Pfad = "C:/Users/daniele/desktop/" + Console.ReadLine();
                var x = new StreamReader(Pfad);
                x.Close();
                string[] Zeilen = File.ReadAllLines(Pfad);
                Console.WriteLine(Zeilen[0] + " hat bisher " + Zeilen[1] + " Klimmzuege geschafft");
                Console.WriteLine(Zeilen[2] + " hat bisher " + Zeilen[3] + " Klimmzuege geschafft");
                int alteAnzahlDani = int.Parse(Zeilen[1]);
                int alteAnzahlUrs = int.Parse(Zeilen[3]);
                Console.WriteLine("Wieviele Klimmzuege hat " + Zeilen[0] + " geschafft?");
                string NeuDani = Console.ReadLine();
                int NeueAnzahlDani = int.Parse(NeuDani);
                int DaniTotalNeu = alteAnzahlDani + NeueAnzahlDani;
                Console.WriteLine("Wieviele Klimmzuege hat " + Zeilen[2] + " geschafft?");
                string NeuUrs = Console.ReadLine();
                int NeueAnzahlUrs = int.Parse(NeuUrs);
                int UrsTotalNeu = alteAnzahlUrs + NeueAnzahlUrs;
                var Dat = new StreamWriter(Pfad);
                Dat.WriteLine(Zeilen[0]);
                Dat.WriteLine(DaniTotalNeu);
                Dat.WriteLine(Zeilen[2]);
                Dat.WriteLine(UrsTotalNeu);
                Dat.Close();
            }
        }
    }
}


Grüsse
interessierter
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 17.06.12 20:36 
Was du in Methoden auslagern willst, bleibt dir überlassen und hängt davon ab, was du später noch vor haben solltest.

Also Dinge, die aufwendig sind, oder sich oft wiederholen.

ALso z.B. das Schreiben und Lesen einer Datei kommt in eine Methode. Wenn du dir ein festes Prinzip überlegst, wie du die Datei aufbaust (das solltest du und dann am besten so, dass es leicht erweiterbar ist) dann würde ich das auch wieder in eine extra Methode legen, die einen String zurück gibt. Denn dann brauchst du diese Methode nur noch auf rufen und die Schreibe- und Lese-Methoden bleiben übersichtlich.


Außerdem würde ich mir noch überlegen, wie ich eine schnelle Erweiterung der Möglichkeiten im Programm einbaue. Theoretisch ist das sehr umständlich, deshalb wurde ja auch das Prinzip der objektorientierten Programmierung erschaffen und das könntest du bei diesem Problem durchaus gut gebrauchen.


Da sich die verschiedenen Möglichkeiten aber im Prinzip eigentlich nur vom Namen unterscheiden und im Endeffekt ja nur gezählt wird, wird das dennoch nicht schwer sein, denn du kannst alles über die selbe Methode machen und der nur den Namen der Möglichkeit (also Liegestützen, oder Klimmzüge) als String übergeben und die Methode legt das einfach in den Text hinein und gibt die Info auch weiter zum schreiben der Datei.

Für diesen Beitrag haben gedankt: interessierter