Entwickler-Ecke

IO, XML und Registry - Bestimmten String aus txt datei lesen C#


Vegeto - Do 21.11.13 10:34
Titel: Bestimmten String aus txt datei lesen C#
Hallo,

ich habe gerade eine vollkommene Blockade im Kopf und komme einfach nicht auf die Lösung, die denke ich nicht so schwer ist :/

Also ich habe eine txtdatei(die in etwa so aufgebaut ist):

Aktivität:bli bli
Ort:bla bla
Name:blubb blubb
Datum:11.02.2011 Uhrzeit:12.59

Aktivität:bli bli
Ort:bla bla
Name:blubb blubb
Datum:11.02.2011 Uhrzeit:14.55

Aktivität:bli bli
Ort:bla bla
Name:blubb blubb
Datum:12.02.2011 Uhrzeit:08.32

Und so weiter...

Auf der GUI befindet sich ein DateTimePicker, wie kann ich jz wenn ich jz z.B. 11.02.2011 auswähle, dass er mir diese beiden Datensätze in einer TextBox auf der GUI anzeigt?

Ich hoffe jmd kann mir brauchbare Tipps geben :)

Lg


baumina - Do 21.11.13 11:33

Du baust dir einen record auf, der Aktivität, Ort, Name, Datum und Uhrzeit als Felder beinhaltet.
Dann machst du dir eine Liste of record.
Dann liest du die Textdatei ein und füllst dabei deine Liste.
Dann bringst du deiner Liste noch bei, dass sie dir alle Einträge eines Datums ausspuckt.


jfheins - Do 21.11.13 12:39

@baumina: es geht hier um C# :wink:

Ich würde s so ähnlich machen wie hier: http://www.entwickler-ecke.de/topic_StreamReader+programmieren++Allgemeine+Frage_110918,0.html
Also einen StreamReader hernehmen und die Datei Zeile für Zeile einlesen.

Da deine Einträge auf mehrere Zeilen verteilt sind, kannst du auch erstmal alle trennen (string.split mit einer leerzeile sollte es tun) und dann einzeln objekte erzeugen. Irgendwo muss natürlich das Parsing stattfinden, das hängt ein wenig davon ab wie das ganze auf Fehlerfälle reagieren soll.
(Ist immer nur genau eine Leerzeile zwischen den Einträgen? Was passiert mit doppelten Zuweisungen? Was passiert, wenn kein Name spezifiziert ist?)

Das filtern sollte schließlich ganz einfach mit einer LINQ Abfrage erledigt sein.


baumina - Do 21.11.13 12:44

Oh, sorry, ich bin irgendwie automatisch davon ausgegangen, dass es in C# auch so ne Art records, Listen und Klassen gäbe. Muss mich wohl doch mal mit dieser Sprache vertraut machen.


Vegeto - Do 21.11.13 13:12

Hallo baumina,

danke, aber wie von jfheins gesagt, es handelt sich um C# :)
Danke trotzdem.

Hallo jfheins,
danke für den Link werde ich mir angucken :)

Doch in der Zeit wo Ihr mir geschrieben habt, habe ich es auch teilweise mit der Linq abfrage geschafft, aber dafür müssen sie die Einträge in einer Zeile befinden.

Daher passt das was du (jfheins) mir gegeben hast ziemlich gut.

Danke^^


jfheins - Do 21.11.13 13:20

user profile iconbaumina hat folgendes geschrieben Zum zitierten Posting springen:
Oh, sorry, ich bin irgendwie automatisch davon ausgegangen, dass es in C# auch so ne Art records, Listen und Klassen gäbe. Muss mich wohl doch mal mit dieser Sprache vertraut machen.

Gibt es schon, nur records heißen structs. (Generische Listen gibt es in beiden Sprachen) Und ich würde dafür eine Klasse empfehlen, keinen struct. Ich wollte dich auch nur kurz darauf aufmerksam machen bevor du anfängst übermäßig viel Delphi-spezifisches zu posten.


Palladin007 - Do 21.11.13 19:28

Also ich würde erst einmal mit der File.ReadAllLines [http://msdn.microsoft.com/de-de/library/s2tte0y1%28v=vs.110%29.aspx] Methode alle Zeilen aus geben lassen.

Dann brauchst du von irgendwo die Bezeichnungen, die vor dem Doppelpunkt stehen.

Dann gehst du jede Zeile durch und suchst in jeder Zeile nach einer Zeichenfolge, die von diesem Regex-Pattern aus gegeben wird:

C#-Quelltext
1:
2:
var propertyName = "Aktivität";
var patternString = "^" + propertyName + @":(?<value>.{1,})$"


Du suchst für jede Zeile und dem oben generierten PatternString nach einem Wert:


C#-Quelltext
1:
2:
3:
4:
5:
6:
var match = Regex.Match(zeile, patternString );

var value = "";

if (match.Success)
    value = match.Groups["value"].Value;



Das hat den Vorteil, dass das nicht unbedingt geordnet sein muss.
Du musst dir dann nur überlegen, wie du die Werte richtig verarbeitest, dass die auch korrekt zueinander einsortiert werden können.

By the way:
Ich hab den Code oben nicht getestet, kann also sein, dass da noch Fehler sind. So weiß ich z.B. nicht, ob der Doppelpunkt in dem Regex-Pattern so alleine stehen bleiben darf.


Vegeto - Fr 22.11.13 10:47

Hallo,

ALSO ich habe mal den Link von jfheins durch geguckt und dort muss man ja mit Regex arbeiten, dann habe ich das von Palladin007 angegcukt und auch dort ist Regex.
Zunächst muss ich mich also in Regex einlesen :/

Naja, ich mach das schon, langsam und ruhig.

Danke

@Palladin007
bei der Codestelle

C#-Quelltext
1:
var match = Regex.Match(zeile, patternString );                    

kommt der Fehler:
Zitat:
Für das nicht statische Feld, die Methode oder die Eigenschaft "System.Text.RegularExpressions.Regex.Match(string, int)" ist ein Objektverweis erforderlich.

Dennoch danke :)

Danke an alle Posts :)

Schönes WE


Palladin007 - Fr 22.11.13 17:17

Naja, eigentlich ist Regex nicht zwingend, aber hier wahrscheinlich deutlich angenehmer zu handhaben.

Die andere Variante wäre, wenn du nicht Regex verwenden möchtest, dass du dann den String händisch zerlegst und raus suchst, was du haben möchtest. Eine Variante wäre, dass du jede Zeile via Split(':') auf teilst und das zweite Element im Ergebnis-Array ist ein Wert.


Regex finde ich hier einfach einfacher zu handhaben.
So schwer ist das auch gar nicht. Ich finde, es sieht am Anfang einfach nur extrem kompliziert und schwer aus.
Was allerdings dann wirklich schwer wird, ist z.B. ein Regex-Pattern, der prüfen soll, ob ein String eine korrekte eMail-Adresse ist. Aber da gibts auf msdn bereits ein Vorgefertigtes.



Zu dem Fehler:

Das kapier ich nicht. Ich habs so bei mir eingefügt und bekomme keinen Syntax-Fehler. Erklären kann ich mir das jetzt nicht, aber wenn er eine Instanz haben will, dann gib ihm doch einfach eine Instanz:


C#-Quelltext
1:
var match = new Regex(patternString).Match(zeile);                    


Das sollte das Gleiche tun, aber auch hier gilt: Getestet ist es nicht, ich weiß nur sicher, dass es bei mir keinen Syntax-Fehler bringt. ^^





PS:

So als kleine Idee kannst du ja einen Algorithmus schreiben, der deine Dateien einlesen und schreiben kann, ähnlich wie mit XML.
Das sollte ganz gut möglich sein, wenn du den Namen der Property und den Wert.ToString nimmst. Du kannst dann ja auch noch hin gehen und passende Attribute schreiben, die z.B. den Namen anders vor geben, vor geben, wie der Wert hin und her geparst werden soll, oder ob die Property ganz ignoriert werden soll.
Das macht die XML-Implementierung auch, sie schaut sich den Typ an, sucht sich Name und Typ raus und schreibt dann das Ganze als String, nur im XML-Format.


By the way:

Warum nimmst du nicht einfach gleich XML?
Macht ungefähr das Gleiche, bloß kann es das deutlich umfangreicher und flexibler.
Außerdem gibt es das bereits fertig implementiert im .NET-Framework. ^^


Ralf Jansen - Fr 22.11.13 17:35

Zitat:
Was allerdings dann wirklich schwer wird, ist z.B. ein Regex-Pattern, der prüfen soll, ob ein String eine korrekte eMail-Adresse ist. Aber da gibts auf msdn bereits ein Vorgefertigtes.

Es ist nicht schwer sondern fast unmöglich ;)
Probier mal irgendein Regex mit folgender EMail-Adresse.

Quelltext
1:
"ralf,jansen"."@work"@unternehmen.de                    


Das Format ist zwar deprecated aber gültig ;)


Palladin007 - Fr 22.11.13 17:46

Also werden alle Zeichen zwischen Anführungszeichen akzeptiert? Oder was ist das da für eine Regel?

Sieht ja verrückt aus :D

Aber testen, ob sie korrekt ist, das ist nur mit Regex unmöglich? Oder wie bekommt der eMail-Provider (wie man die auch immer nennt), raus, ob die Adresse stimmt? Der muss die ja auf irgendwelche Dinge prüfen und untersichen um die notwendigen Daten zum versenden der eMail zu kommen.



Aber wir weichen vom Thema ab. ^^

Hast du denn eine Idee, wo der Fehler von Vegeto kommt? Ich hab alle .NET-Versionen durch getestet, überall gibt es die Regex-Klasse und sie hat immer eine statische Methode namens Match.


Ralf Jansen - Fr 22.11.13 18:22

Zitat:
Also werden alle Zeichen zwischen Anführungszeichen akzeptiert? Oder was ist das da für eine Regel?

[url]isemail.info[/url]
Erklärt auch warum etwas gültig/ungültig ist(mit C# Source übrigens)

Zitat:
Hast du denn eine Idee, wo der Fehler von Vegeto kommt? Ich hab alle .NET-Versionen durch getestet, überall gibt es die Regex-Klasse und sie hat immer eine statische Methode namens Match.


Der Compiler versucht die Regex.Match(string, int) Überladung nicht die mit 2 strings. Irgendwas hat er also mit den zeile bzw. patternString Parametern angestellt so das der diese Überladung für passender (aber eben nicht passen genug) hält.