kostenloser Webspace werbefrei: lima-city


Visual C# - String "trennen" ?

lima-cityForumProgrammiersprachenProgrammieren mit .NET & Mono

  1. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    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:wall:
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. m**********n

    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
  4. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    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 ?!? :confused:
  5. Hallo philip-felder,

    hier hast Du ein funktionierendes Beispiel:
    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));
    }
    Der Aufruf muss dann folgendermaßen sein:
    int links, rechts;
    
    parseInput("R12RL55L\n", out links, out rechts);
  6. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    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?
  7. Hallo philip-felder,

    eine Möglichkeit für den zweiten Fall wäre:
    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]);
        }
    }
    Der Beispielaufruf sieht folgendermaßen aus:
    int links, rechts;
    
    parseInput("Rechts: 55\nLinks: 12\n", out links, out rechts);

    Den ersten Fall kann man noch etwas verallgemeinern:
    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');
    }
    Dann sieht es etwas einfacher aus.

    Edit: Bufgix für extractInt().



    Beitrag zuletzt geändert: 4.6.2011 19:44:12 von darkpandemic
  8. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    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 :frown:
    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
  9. Hallo philip-felder,

    ich gehe jetzt mal davon aus, dass Du die zweite Methode verwendest (ich empfehle jetzt einfach mal die Erste :biggrin:).
    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:
    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];
    }
    Jetzt ist es auch wieder weniger Code.

  10. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    Das klappt leider nicht ;-<
    Die labels bleiben unverändert.
  11. Hallo philip-felder,

    was genau steht den in der Variable lesen?
  12. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    In lesen steht immer (unendlich) abwechselnd (ohne Pause)
    Links: 0049
    und
    Rechts: 0059
    !

    Beitrag zuletzt geändert: 4.6.2011 20:41:29 von philip-felder
  13. Also ich habe mir hier folgenden Test-Code gebastelt und der funktioniert:
    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]);
    Was steht den in tokens nach dem Split()?
  14. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    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
  15. 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'});
    }
  16. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    Aber wieso friert das Programm ein?
    Kann man das auch mit einem backgroundworker machen, sodass es nicht einfriert?
  17. 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:
    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();
            }
        }
    }
    Ich habe den Labels besser Namen verpasst (lblLeft und lblRight)
  18. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    @darkpandemic Du hast gerade alle meine Probleme gelöst (schon wieder)! Vielen Dank :wink:
  19. Aber diesmal könnte ich früher ins Bett :biggrin:
  20. Autor dieses Themas

    philip-felder

    philip-felder hat kostenlosen Webspace.

    darkpandemic schrieb:
    Aber diesmal könnte ich früher ins Bett :biggrin:


    Ja, vielleicht kommt noch was, die nacht ist noch jung ;->
  21. heroes-of-legends

    heroes-of-legends hat kostenlosen Webspace.

    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
  22. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!