Hallo, Ich habe eine Software die Daten sendet und eine die sie über einen virtuellen Port empfängt. Beide Anwendungen sind in C# Forms programmiert. Die sendende Anwendung schickt in unterschiedlichen Intervallen, unterschiedliche Zeilenanzahlen. Die gesendeten Daten haben das Format S0P0N0 \r\n (die Nullen sind die Werte die sich ändern), Ich bin gerade ratlos wie ich das Problem mit unterschiedlicher Zeilenzahl handeln kann und wie ich am besten die 3 Werte wieder aus dem String extrahiere. Das Sendeprotokoll könnte ich falls nötig relativ leicht ändern. Ich hoffe jemand kann mir weiterhelfen, MfG. Christoph
Grundsätzlich geht immer die Regex.Match-Methode; hier geht es mit der String.Split-Methode noch einfacher:
1 | String.Split(new Char[] {'S', 'P', 'N'}, "S0P0N0") |
2 | // returns {"0", "", "0", "", "0"}
|
… oder so ähnlich. VG Torsten
Ist eine Instanzmethode, also
1 | var s = "S0P0N0"; |
2 | var x = s.Split(new [] { 'S', 'P', 'N' }, StringSplitOptions.RemoveEmptyEntries); |
3 | // Dann Fehlerprüfung und Typumwandlung ... |
Christoph schrieb: > Ich bin gerade ratlos wie ich das Problem mit > unterschiedlicher Zeilenzahl handeln kann Den entsprechenden Code für jede Zeile ausführen (Schleife)?
Nachtrag: Als Separatoren-Array kann man natürlich auch eine (readonly) Klassenvariable verwenden anstatt es immer wieder neu zu erzeugen.
Meisterklops schrieb: > Ist eine Instanzmethode Blöde Instanzmethoden! :( Da hätten die auch eine Extension draus machen können! ;)
1 | public static class myString { |
2 | static String[] Split(this String S, char[] chrs) { |
3 | return S?.Split(chrs); |
4 | }
|
5 | }
|
Ich war in Gedanken bei String.Join(). Sorry + Danke, Meisterklops! > Den entsprechenden Code für jede Zeile ausführen (Schleife)? … und dann vorher mit s?.Split(null) die Zeilen finden? Oder eben mit einer RegEx in einem einzigen Schritt: https://msdn.microsoft.com/library/b873y76a(v=vs.110).aspx Kapitel "Alternatives to String.Split".
:
Bearbeitet durch User
Danke! Werd das gleich mal in mein Programm einbauen und testen, nur das Empfangen ist damit noch immer nicht gelöst. Wenn der serialPort ein "DataReceivedEvent" auslöst werden ja alle empfangenen Daten in den Empfangspuffer geschrieben oder? Also pro ausgelöstem Event eine Zeile lesen funktioniert nicht oder? MfG. Christoph
Christoph schrieb: > Wenn der serialPort ein "DataReceivedEvent" auslöst werden ja alle > empfangenen Daten in den Empfangspuffer geschrieben oder? Wenn der SerialPort ein "DataReceivedEvent" auslöst, dann bedeutet das, dass neue Daten in den Empfangspuffer geschrieben wurden. Vielleicht meitest Du das so? Mit SerialPort.Read(…) oder SerialPort.ReadExisting() werden alle empfangenen Daten aus dem Empfangspuffer gelesen. Mit SerialPort.ReadLine() nur eine Zeile. Aber SerialPort.ReadLine() wartet und hält Deinen Thread an. Benutzt Du einen BackgroundWorker oder sowas wie "readWriteThread = new System.Threading.Thread(readWrite)"? > Also pro ausgelöstem Event eine Zeile lesen funktioniert nicht oder? Richtig. System.IO.Ports.SerialPort bietet keinen fertigen NewLineReceivedEvent 'out of the box' an.
:
Bearbeitet durch User
Torsten C. schrieb: > Benutzt Du einen BackgroundWorker oder …? > Christoph schrieb: >> Also pro ausgelöstem Event eine Zeile lesen funktioniert nicht oder? > Richtig. System.IO.Ports.SerialPort bietet keinen fertigen > NewLineReceivedEvent 'out of the box' an. PS: Beim BackgroundWorker würde das 'NewLineReceivedEvent' nur anders heißen, also 'BackgroundWorker.ProgressChanged'. Ich bevorzuge aber System.Threading.Thread mit selbst definiertem NewLineReceivedEvent. Nutzt Du das Windows-Presentation-Framwork oder Windows-Forms? Je nachdem wird das Ereignis dann über Invoke im UI-Thread ausgelöst.
ich habe ähnliches Problem vor kurzen gehabt. Allerdings habe ich in Python das Testprogramm geschrieben. Wenn das Telegramm kontinuierlich gesendet wird, muss du zunächst synchronisieren. Pseudocode data = ser.read(TELEGRAM_LENGTH) # damit fällt sicher ein volles Telegramm hinein idx = data.find(TELEGRAM_START) # muss eindeutig sein (Verwechslung mit Daten prüfen) start = data.substring(idx,end) telegram = start + ser.read(TELEGRAM_LENGTH - length(start ))
daniel schrieb: > idx = data.find(TELEGRAM_START)… Das läuft also auf einen weiteren, einen eigenen Empfangspuffer hinaus. In C# würde sich dafür ein StringBuilder anbieten. Christoph schrieb: > Beide Anwendungen sind in C# Forms programmiert. Das hatte ich gestern übersehen. Also sähe das Event dann so ähnlich aus:
1 | // Deklaration:
|
2 | public event EventHandler<String> NewLineReceivedEvent; |
3 | // Auslösen aus dem readWriteThread dann mit:
|
4 | string EmpfangeneZeile = "S0P0N0"; // vorher mit StringBuilder.Remove() entfernt |
5 | this.Invoke((MethodInvoker)(() => { |
6 | EventHandler<string> handler = NewLineReceivedEvent; |
7 | handler(this, EmpfangeneZeile); |
8 | }));
|
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.