| Autor |
Beitrag |
Terrenay
Hält's aus hier
Beiträge: 15
|
Verfasst: Fr 31.01.14 23:20
Erstmal vorweg, ich bin erst 13 und programmiere noch nicht sehr lange, also nehmt es mir bitte nicht übel, wenn diese Frage einfach zu beantworten sein sollte
Ich habe in der letzten Woche ein klitzekleines Kampfspiel, ähnlich wie Pokemon programmiert, und darin geht es halt darum, möglichst viele Runden zu überleben.
Jetzt möchte ich, dass beim Beenden des Programms die aktuelle Runde in eine Datei geschrieben wird, und beim nächsten Start in etwa so ausgegeben wird: "Willkommen zurück! Dein bisheriger Highscore liegt bei Runde SoUndSo".
Aber ich weiss nicht, wie genau ich das machen soll
Im Moment habe ich es einfach so implementiert, dass die erreichte Runde des letzten Spiels ausgegeben wird.
Das sieht so aus:
Bei Aufruf des FormLoad-Events:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| StreamReader sr = new StreamReader("NexusHighscore.txt"); int Highscore = int.Parse(sr.ReadToEnd()); if (File.Exists("NexusHighscore.txt")) { MessageBox.Show("Willkommen zurück! \r\nAls du das letzte Mal gespielt hast, hast du folgende Runde erreicht: " + Highscore, "Willkommen Zurück!"); } sr.Close(); |
Bei Aufruf des FormClosing-Events:
C#-Quelltext 1: 2: 3: 4:
| StreamWriter sw = new StreamWriter("NexusHighscore.txt"); sw.WriteLine(Variablen.Runde); sw.Flush(); sw.Close(); |
Bei diesem Code bekomme ich übrigens auch einen Fehler, aber nur, wenn ich das Programm zum ersten Mal starte, sprich, die Datei "NexusHighscore.txt" noch nicht vorhanden ist. Aber ich habe doch mit File.Exists getestet, ob die Datei vorhanden ist?!
Kann mir bitte jemand helfen?
Moderiert von Christian S.: Code- durch C#-Tags ersetzt
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Fr 31.01.14 23:41
Hallo und  !
Das sieht ja schon mal nicht schlecht aus
Der Grund, warum die Fehlermeldung bekommst, ist, weil Du die Existenz der Datei erst prüfst, nachdem Du versucht hast, daraus zu lesen. Lesen tust Du ja hier
C#-Quelltext 1: 2:
| StreamReader sr = new StreamReader("NexusHighscore.txt"); int Highscore = int.Parse(sr.ReadToEnd()); |
und die Prüfung kommt erst später.
Das heißt, die if-Abfrage für die Prüfung der Existenz der Datei muss um alles herum, was auf diese Datei angewiesen ist:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| if (File.Exists("NexusHighscore.txt")) { StreamReader sr = new StreamReader("NexusHighscore.txt"); int Highscore = int.Parse(sr.ReadToEnd()); sr.Close(); MessageBox.Show("Willkommen zurück! \r\nAls du das letzte Mal gespielt hast, hast du folgende Runde erreicht: " + Highscore, "Willkommen Zurück!"); } |
Wie Du siehst, habe ich auch das Schließen des Streams ein wenig vorgezogen, weil es keinen Grund gibt, den noch länger offen zu halten.
Nun noch zwei Dinge, die man IMHO verbessern sollte.
Zuerst einmal: Du gibst bei der Datei kein Verzeichnis an, das heißt es wird das "aktuelle" Verzeichnis benutzt. Zum einen ist das nicht immer so definiert, wie man das gerne hätte, zum anderen ist es meistens das Verzeichnis, in dem die Anwendung liegt. In den meisten Windows-Versionen hat man dazu aber keinen Schreibzugriff. Ich würde die Datei daher in das Benutzerverzeichnis schreiben:
C#-Quelltext 1: 2: 3: 4: 5:
| var folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Dein Name", "Name Deiner Anwendung"); if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
var filePath = Path.Combine(folderPath, "NexusHighscore.txt"); |
Und dann, das ist das die zweite Sache, würde ich den Zugriff auf die Datei so absichern, dass die entsprechenden Systemresourcen immer freigegeben werden, auch wenn ein Fehler passiert. Das macht man am Besten über die using-Anweisung:
C#-Quelltext 1: 2:
| using (StreamWriter sw = new StreamWriter(filePath)) sw.Write(Variablen.Runde); |
Die sorgt automatisch dafür, dass auch im Fehlerfall die Resourcen freigegeben werden und im "Normalfall" übernimmt sie auch das Schließen des Streams für einen.
Ich hoffe, das hilft schon mal weiter, ansonsten einfach fragen
Viele Grüße
Christian
P.S.: Das man das Verzeichnis erstellt, macht natürlich nur Sinn, wenn man Reinschreiben will. Wenn man nur lesen will, reicht es, zu schauen, ob die Datei existiert.
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Für diesen Beitrag haben gedankt: FinnO, Terrenay
|
|
Palladin007
      
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Sa 01.02.14 02:56
Du kannst dir auch mal die Methode File.ReadAllLines anschauen. Da sparst du dir das Ganze drum herum und bekommst direkt alle Zeilen aus der Datei gelesen.
Prüfen, ob die Datei/das Verzeichnis existiert, musst du aber trotzdem.
Oder File.ReadAllText, ach was, schau dir einfach die ganze File-Klasse an
Für einfache Arbeiten mit Dateien bringt die eigentlich alles Nötige mit und du musst dich gar nicht selber um das Öffnen und Schließen der Datei kümmern.
Moderiert von Th69: C#-Tags hinzugefügt
Für diesen Beitrag haben gedankt: Terrenay
|
|
Terrenay 
Hält's aus hier
Beiträge: 15
|
Verfasst: Sa 01.02.14 10:55
Danke für die Antworten  werds nachher gleich mal ausprobieren!
Etwas wichtiges habe ich leider vergessen zu erwähnen: Eigentlich möchte ich nicht, dass es einfach die letzte erreichte Runde ausgibt, sondern die höchste, die jemals erreicht wurde!
Als ich das einmal ausprobiert habe, bekam ich aber jedes zweite Mal eine exception und in den anderen fällen einfach die letzte erreichte runde
Versteht ihr, was ich meine?
@Christian: Und wie mache ich das dann, wenn ich das Programm zB einem Freund zum downloaden geben will? Dann ändert sich ja der Name des Benutzers ^^
EDIT: Habs geschafft, dass es den Highscore speichert  Danke Palladin007 für den Tipp mit den File.-Befehlen
Danke auch @Christian, für die Prüfung, ob die Datei existiert ^^ Funktioniert soweit einwandfrei, allerdings ist immer noch die Frage offen, wie der Pfad dann auch für einen anderen Benutzer gültig ist... Kann mir da vielleicht auch noch jemand helfen?
So hab ich den Highscore jetzt gespeichert:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| try { string x = File.ReadAllText("NexusHighscore.txt").ToString(); int y = int.Parse(x);
if (Variablen.Runde > y) File.WriteAllText("NexusHighscore.txt", Variablen.Runde.ToString()); } catch { File.WriteAllText("NexusHighscore.txt", Variablen.Runde.ToString()); } |
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 01.02.14 12:52
Hallo Terrenay,
das ApplicationData-Verzeichnis ist schon benutzergebunden (s. Environment.SpecialFolder-Enumeration), d.h. es reicht einfach
C#-Quelltext 1:
| var folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Name Deiner Anwendung"); |
Für diesen Beitrag haben gedankt: Terrenay
|
|
Terrenay 
Hält's aus hier
Beiträge: 15
|
Verfasst: Sa 01.02.14 13:05
Vielen Dank, hat sofort funktioniert
Damit wären auch schon alle meine Fragen geklärt
Danke für eure Zeit ^^
Moderiert von Th69: Vollzitat entfernt.
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Sa 01.02.14 13:43
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Für diesen Beitrag haben gedankt: Terrenay
|
|
Th69
      

Beiträge: 4807
Erhaltene Danke: 1061
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 01.02.14 18:44
Hallo Christian,
ach so meintest du das.
Ich habe gerade mal bei mir nachgeschaut: das machen aber meist nur die großen Firmen (Microsoft, Adobe, Mozilla), andere Programme nur direkt mit dem Programmnamen (VLC, FreeDoko). Aber es macht ja auch Sinn, wenn man mehrere Programme anbietet, diese in einen eigenen Unterordner zu stecken.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Sa 01.02.14 19:04
Das ist die Microsoft Empfehlung ich selbst würde es nicht (mehr) so machen . Diese Company/Product Struktur ist eine doppelte Sollbruchstelle beim updaten.
Der arme Entwickler tut mir Leid der zum Beispiel das Upgrade Setup für Delphi schreibt. Der müsste, wenn die sich dran halten, im Borland/Inprise/Codegear/Embarcadero Ordner den entsprechenden Anwendungsunterordner (wenn sich der auch mal geändert hat) nach alten Einstellungen/Setups suchen . Wenn es mal ein Wechsel von x86 nach x64 geben sollte dann auch noch in den zwei verschiedenen Programme-Ordnern. Statisch gesehen ist die Company/Product Empfehlung nett sowohl im Filesystem also auch in der Registry. Bei Software mit Historie eine Bestrafung. Ich glaube Microsoft empfiehlt sogar das neben Company/Product auch die Versionsnummer der Anwendung da mit aufzunehmen ist (zumindest bei user Settings macht das ja .Net automatisch). Eindeutig Empfehlungen eines Unternehmens das jedes Problem mit Manpower erschlagen kann.
|
|
|