Visual C# - String "trennen" ?
lima-city → Forum → Programmiersprachen → Programmieren mit .NET & Mono
aufruf
buchstabe
code
feld
funktionierendes beispiel
http
mache
passende expression
problem
rechts code
rechts links rechts string
sender
start
string
system
text
url
zahl
zeichen
zweite methode
-
Hallo,
Also ich habe ein Asuro, der mir per Uart zwei werte schickt !
Er sender: "R12RL55L\n", die Zahlen zwischen den Buchstaben ändern sich!
In C# habe ich schon ein Serialport:
string lesen = serialPort1.ReadLine();
aber wie mache ich jetzt das in label1 die Zahl, die zwischen den beiden "R"s, steht?
Oder wäre es einfacher wenn er "Links: 55\nRechts: 12\n" sendet?
Vielen dank schonmal jetzt
Philip
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Per Substring: http://msdn.microsoft.com/en-us/library/system.string.substring%28VS.71%29.aspx
Beitrag zuletzt geändert: 4.6.2011 18:00:14 von mator-kaleen -
mator-kaleen schrieb:
Per Substring: http://msdn.microsoft.com/en-us/library/system.string.substring%28VS.71%29.aspx
Ähmm.... Daraus werde ich noch nicht so richtig schlau ?!? -
Hallo philip-felder,
hier hast Du ein funktionierendes Beispiel:
Der Aufruf muss dann folgendermaßen sein:void parseInput(string text, out int links, out int rechts) { int rechts_start, rechts_end, links_start, links_end; rechts_start = text.IndexOf('R'); // finde das erste 'R' rechts_end = text.IndexOf('R',rechts_start+1); // finde das zweite 'R' links_start = text.IndexOf('L'); // finde das erste 'L' links_end = text.IndexOf('L',links_start+1); // finde das zweite 'L' // extrahiere die Zahl zwischen den Buchstaben und konvertiere es zu int: rechts = int.Parse(text.Substring(rechts_start+1,rechts_end-rechts_start-1)); links = int.Parse(text.Substring(links_start+1,links_end-links_start-1)); }
int links, rechts; parseInput("R12RL55L\n", out links, out rechts);
-
Danke, das klappt super!
Und wie geht das mit:
Links: 55\nRechts: 12\n
Weil so wie du es machst, braucht man doch voll viel code, geht das nicht einfacher? -
Hallo philip-felder,
eine Möglichkeit für den zweiten Fall wäre:
Der Beispielaufruf sieht folgendermaßen aus:void parseInput(string text, out int links, out int rechts) { links = 0; rechts = 0; string[] lines = text.Split(new char[] {'\n'}); foreach(string line in lines) { string[] tokens = line.Split(); if(tokens[0] == "Links:") links = int.Parse(tokens[1]); else if(tokens[0] == "Rechts:") rechts = int.Parse(tokens[1]); } }
int links, rechts; parseInput("Rechts: 55\nLinks: 12\n", out links, out rechts);
Den ersten Fall kann man noch etwas verallgemeinern:
Dann sieht es etwas einfacher aus.int extractInt(string text, char marker) { int start, end; start = text.IndexOf(marker); end = text.IndexOf(marker, start+1); return int.Parse(text.Substring(start+1,end-start-1)); } void parseInput(string text, out int links, out int rechts) { links = extractInt(text, 'L'); rechts = extractInt(text, 'R'); }
Edit: Bufgix für extractInt().
Beitrag zuletzt geändert: 4.6.2011 19:44:12 von darkpandemic -
Wenn ich es den String Text fest als Rechts: 55\nLinks: 12\n machen funktioniert es, aber nicht wenn ich es mit dem Serialport mache
string lesen = serialPort1.ReadLine(); int links, rechts; parseInput(lesen, out links, out rechts); label10.Text = rechts.ToString(); label13.Text = links.ToString();
In timer1 mit Interval 1.
Edit: Senden tuhe ich auch das richtige ;->
Edit 2: Der serialport ist natürlich geöffnet und auch schon getestet, daran liegt es nicht ;->
Beitrag zuletzt geändert: 4.6.2011 20:15:29 von philip-felder -
Hallo philip-felder,
ich gehe jetzt mal davon aus, dass Du die zweite Methode verwendest (ich empfehle jetzt einfach mal die Erste ).
Da Du mit ReadLine() liest bekommst Du es bereits zeilenweise, d.h., beim ersten Lesen ist lesen="Rechts: 55" und beim zweiten Lesen ist lesen="Links: 12".
Evtl. könnte man es folgendermaßen machen:
Jetzt ist es auch wieder weniger Code.for(int i=0;i<2;i++) { string lesen = serialPort1.ReadLine(); string[] tokens = lesen.Split(); if(tokens[0] == "Links:") label13.Text = tokens[1]; else if(tokens[0] == "Rechts:") label10.Text = tokens[1]; }
-
Das klappt leider nicht ;-<
Die labels bleiben unverändert. -
In lesen steht immer (unendlich) abwechselnd (ohne Pause)
undLinks: 0049
!Rechts: 0059
Beitrag zuletzt geändert: 4.6.2011 20:41:29 von philip-felder -
Also ich habe mir hier folgenden Test-Code gebastelt und der funktioniert:
Was steht den in tokens nach dem Split()?string lesen = "Links: 0049"; string[] tokens = lesen.Split(); if(tokens[0] == "Links:") Console.WriteLine("L: " + tokens[1]); else if(tokens[0] == "Rechts:") Console.WriteLine("R: " + tokens[1]); lesen = "Rechts: 0059"; tokens = lesen.Split(); if(tokens[0] == "Links:") Console.WriteLine("L: " + tokens[1]); else if(tokens[0] == "Rechts:") Console.WriteLine("R: " + tokens[1]);
-
In token[0] steht das selbe :
Rechts:0747
Edit:
habe vergessen ein Leerzeichen zwischen Rechts: und 0012 zu senden, jetzt steht in tokens[0]:
Rechts:
Beitrag zuletzt geändert: 4.6.2011 21:02:02 von philip-felder -
Dann sollte es jetzt ja funktionieren.
Die führenden Nullen kannst Du wie folgt los werden:
for(int i=0;i<2;i++) { string lesen = serialPort1.ReadLine(); string[] tokens = lesen.Split(); if(tokens[0] == "Links:") label13.Text = tokens[1].TrimStart(new char[] {'0'}); else if(tokens[0] == "Rechts:") label10.Text = tokens[1].TrimStart(new char[] {'0'}); }
-
Aber wieso friert das Programm ein?
Kann man das auch mit einem backgroundworker machen, sodass es nicht einfriert? -
Hallo philip-felder,
das Programm stoppt bei serialPort1.ReadLine() bis es eine Zeile gelesen hat.Deswegen friert es ein. Ein Thread der das Lesen übernimmt ist da eine mögliche Lösung:
Ich habe den Labels besser Namen verpasst (lblLeft und lblRight)using System; using System.Windows.Forms; using System.Threading; namespace CSharpTest { public partial class MainForm : Form { delegate void SetTextCallback(string Text); Thread readThread; void setLeftLabel(string text) { if (this.lblLeft.InvokeRequired) { SetTextCallback cb = new SetTextCallback(setLeftLabel); this.Invoke(cb, new object[] { text }); } else { this.lblLeft.Text = text; } } void setRightLabel(string text) { if (this.lblRight.InvokeRequired) { SetTextCallback cb = new SetTextCallback(setRightLabel); this.Invoke(cb, new object[] { text }); } else { this.lblRight.Text = text; } } void readThreadProc() { bool flag = false; string lesen; while(true) { //string lesen = serialPort1.ReadLine(); if(flag) { lesen = "Rechts: 0059"; flag = false; } else { lesen = "Links: 0049"; flag = true; } string[] tokens = lesen.Split(); if(tokens[0] == "Links:") setLeftLabel(tokens[1].TrimStart(new char[] {'0'})); else if(tokens[0] == "Rechts:") setRightLabel(tokens[1].TrimStart(new char[] {'0'})); } } public MainForm() { InitializeComponent(); } void MainForm_OnLoad(object sender, EventArgs e) { readThread = new Thread(this.readThreadProc); readThread.Start(); } void MainForm_OnClosing(object sender, FormClosingEventArgs e) { readThread.Abort(); } } }
-
@darkpandemic Du hast gerade alle meine Probleme gelöst (schon wieder)! Vielen Dank
-
Aber diesmal könnte ich früher ins Bett
-
darkpandemic schrieb:
Aber diesmal könnte ich früher ins Bett
Ja, vielleicht kommt noch was, die nacht ist noch jung ;-> -
Hi, zum prüfen der strings kannst du auch Regular Expressions verwenden.
Falls du damit noch nicht gearbeitet hast, schau doch einfach mal hier rein.
Die passende Expression für dein Problem wäre dann in etwa so:
(?<r_l_block>(?<R_L>R|L)(?<value>\d{1,})(?<R_L>R|L)){1,}
Um diesen Ausdruck mal laienverständlich auszudrücken könnte man das so gestalten.
Syntax:
Teilstringdefintion
([X] A, B, C oder 0) - X Zeichen, wobei die Zeichen A, B, C oder 0 sein müssen.
([1]R oder L)([1 oder mehr]beliebige Zahlen)([1]R oder L) <<< und das ganze 1 mal oder mehr
Regular Expressions sind ein sehr mächtiges Werkzeug in programmiersprachen, ich hab damit schon ganze HTML Seiten geparst :D
grüße
Doomdrake -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage