Forum: PC-Programmierung C# string zerlegen und in array speichern


von Ge G. (gege368)


Lesenswert?

Hallo zusammen,
ich habe aus Internet einen code geklaut:

    public static void Main()
    {
        String str = "abc,def,ghi";

        string[] arr = str.Split(",".ToCharArray());


        foreach (string s in arr)
        {
            Console.WriteLine(s + "!");
        }
        Console.WriteLine(arr[0]);
        Console.ReadLine();

    }




Als output bekomme ich:
abc!
def!
ghi!
abc

eigentlich ist der letzte wert "abc" bzw. arr[0] mir wichtig.

Dieses Program funktioniert soweit, wenn ich einen festen string 
vorgebe.

wenn ich einen string von COM-Port bekomme,
funktioniet es mit dem ersten string schon.
Mit dem zweiten string wird es aber nicht mehr gehen, da das program 
arr[0] nix ändern will.

Meine Frage wäre: wie kann der arr[0] nach dem neusten arr[0] angepasst 
werden, sobald ein neuer string mit geändert arr[0] kommt?

Vielen Dank und Gruß
Ge Ge

von Karl H. (kbuchegg)


Lesenswert?

Ge Ge schrieb:


> Mit dem zweiten string wird es aber nicht mehr gehen, da das program
> arr[0] nix ändern will.

Das ist Quatsch.

Ein Programm hat keinen freien Willen und sagt sich "Och, heute ärgere 
ich meinen Programmierer"

Irgendwo wirst du halt einen Fehler eingebaut haben. Aber da du es 
vorziehst, den fehlerhaften Code für dich zu behalten, kann dir niemand 
helfen.

> Meine Frage wäre: wie kann der arr[0] nach dem neusten arr[0] angepasst
> werden, sobald ein neuer string mit geändert arr[0] kommt?

Du dokterst an der falschen Stelle rum.

von Ge G. (gege368)


Lesenswert?

Hallo Karl,

da hast schon Recht.

mein geklauter Code sieht so aus:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace SimpleSerial
{
    public partial class Form1 : Form
    {
        // Add this variable
        string RxString;
        string adc;

        public Form1()
        {
            InitializeComponent();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM4";
            serialPort1.BaudRate = 19200;
            serialPort1.DataBits = 8;
            serialPort1.Parity = Parity.None;
            serialPort1.StopBits = StopBits.One;
            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                buttonStart.Enabled = false;
                buttonStop.Enabled = true;
                textBox1.ReadOnly = false;
            }
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                buttonStart.Enabled = true;
                buttonStop.Enabled = false;
                textBox1.ReadOnly = true;
            }

        }

        private void Form1_FormClosing(object sender, 
FormClosingEventArgs e)
        {
            if (serialPort1.IsOpen) serialPort1.Close();
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs 
e)
        {
            // If the port is closed, don't try to send a character.
            if (!serialPort1.IsOpen) return;

            // If the port is Open, declare a char[] array with one 
element.
            char[] buff = new char[1];

            // Load element 0 with the key character.
            buff[0] = e.KeyChar;

            // Send the one character buffer.
            serialPort1.Write(buff, 0, 1);

            // Set the KeyPress event as handled so the character won't
            // display locally. If you want it to display, omit the next 
line.
            e.Handled = true;
        }



        private void DisplayText(object sender, EventArgs e)
        {
            textBox1.AppendText(RxString);

            string[] arr = RxString.Split(",".ToCharArray());

            textBox2.AppendText(arr[2]);
        }

        private void serialPort1_DataReceived(object sender, 
System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            RxString = serialPort1.ReadExisting();
            this.Invoke(new EventHandler(DisplayText));
        }


        private void button3_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Write("BCAST:0012,04=lampe1,adc,255,\r\n");
                buttonStart.Enabled = false;
                buttonStop.Enabled = true;
                textBox1.ReadOnly = false;
            }
        }




        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            String trackerbara = Convert.ToString(trackBar2.Value);
            label2.Text = trackerbara;
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }



    }
}






Mein Problem besteht in der Mitte, da wo " private void DisplayText " 
ist.
Es ist so, mein Programm bekommt immer einen String mit einer Format 
"abc,def,hij,klm". Der wird dann unter RxString gespeichert. Dieser 
RxString wird auch richtig in textBox1 gezeigt.

Jetzt ist so, ich brauche z.B. der dritte Teil des Strings, "hij".
Deswegen habe ich diese splitt funktion genommen. Mein Program bekommt 
ersten string RxString, "hij" wird richtig gezeigt, sobald mein Program 
den zweiten String bekommt, kommt dann fehler, irgendwas wegen array 
blabla...

Was meinst? Woran liegt dann das Fehler?
Danke und Grüße

GeGe

von Peter II (Gast)


Lesenswert?

Ge Ge schrieb:
> kommt dann fehler, irgendwas wegen array
> blabla...
genau das ist aber wichtig was da kommt!!!!!!!!

Vermutlich greifst du auf eine STelle im Array welche nicht da ist. Dein 
split liefert also nicht 3 oder mehr teile zurück.

Lass dir doch mal das array anzeigne welchen zurückgegen wird. (mit 
foreach als debug )

von Arc N. (arc)


Lesenswert?

Ge Ge schrieb:

> Was meinst? Woran liegt dann das Fehler?
> Danke und Grüße

DataReceived und/oder DisplayText...
DataReceived kann, je nach dem was/wie angeschlossen ist/gesendet wird, 
auch mal nach nur ein zwei Bytes/Zeichen (SerialPort.Encoding) 
aufgerufen werden. Z.B. statt "abc,def,hij,klm" kommt beim ersten 
Ereignis "ab", beim zweiten "c", beim dritten ",def" usw. Wenn dann 
Split aufgerufen wird, steht in arr nicht das, was erwartet wurde.
Also entweder in DataReceived so lange einen Buffer auffüllen bis die 
gesamte Antwort da ist und dann auswerten oder z.B. mit einem separaten 
Thread und ReadLine (SerialPort.NewLine beachten) arbeiten.

> GeGe

von Ge G. (gege368)


Lesenswert?

Peter II schrieb:
> Ge Ge schrieb:
>> kommt dann fehler, irgendwas wegen array
>> blabla...
> genau das ist aber wichtig was da kommt!!!!!!!!
>
> Vermutlich greifst du auf eine STelle im Array welche nicht da ist. Dein
> split liefert also nicht 3 oder mehr teile zurück.
>
> Lass dir doch mal das array anzeigne welchen zurückgegen wird. (mit
> foreach als debug )

Hallo Peter,

habe ich nachgeschaut, also, da steht folgende Fehlerbeschreibung:

IndexOutOfRangeException was unhandled by user code
Der Index war außerhalb des Arraybereichs.


Der Code funktioniert mit einem ungeänderten String schon, aber sobald 
neue von COMPort bekommt,dann fehler.

Kann es auch dran liegen, dass der String von COMport mit startbyte zu 
tun?

danke!
Gruß

von Peter II (Gast)


Lesenswert?

Ge Ge schrieb:
> Kann es auch dran liegen, dass der String von COMport mit startbyte zu
> tun?
nein der grund wird wie schon "Arc Net" geschrieben hat, daran liegen 
das du nicht den kompletten string auf einmal bekommst. Warum Debuggst 
du den code nicht einfach?

von Ge G. (gege368)


Lesenswert?

Arc Net schrieb:
> Ge Ge schrieb:
>
>> Was meinst? Woran liegt dann das Fehler?
>> Danke und Grüße
>
> DataReceived und/oder DisplayText...
> DataReceived kann, je nach dem was/wie angeschlossen ist/gesendet wird,
> auch mal nach nur ein zwei Bytes/Zeichen (SerialPort.Encoding)
> aufgerufen werden. Z.B. statt "abc,def,hij,klm" kommt beim ersten
> Ereignis "ab", beim zweiten "c", beim dritten ",def" usw. Wenn dann
> Split aufgerufen wird, steht in arr nicht das, was erwartet wurde.
> Also entweder in DataReceived so lange einen Buffer auffüllen bis die
> gesamte Antwort da ist und dann auswerten oder z.B. mit einem separaten
> Thread und ReadLine (SerialPort.NewLine beachten) arbeiten.
>
>> GeGe

Ah jetzle...
Deswegen zeige der textBox1 zum zweiten Mal auch keinen 
"abc,def,hij,klm" sondern nur "ab"... dann ist das programm stehen 
geblieben.
Wo gibt es eigentlich mehr info über receiveBuffer oder thread oder 
readline?  Danke Arc Net!
Gruß

von Ge G. (gege368)


Lesenswert?

Peter II schrieb:
> Ge Ge schrieb:
>> Kann es auch dran liegen, dass der String von COMport mit startbyte zu
>> tun?
> nein der grund wird wie schon "Arc Net" geschrieben hat, daran liegen
> das du nicht den kompletten string auf einmal bekommst. Warum Debuggst
> du den code nicht einfach?

freue mich,dass Ihr für mich da seid.

Der Grund ist ganz einfach, ich bin ner Anfänger erst ab paar wochen...
aber es macht spass...

von Peter II (Gast)


Lesenswert?

Ge Ge schrieb:
> Wo gibt es eigentlich mehr info über receiveBuffer oder thread oder
> readline?
msdn

einfach bei google "msdn readline serial" suchen

von Ge G. (gege368)


Lesenswert?

danke euch alle!
Ich werde paar tage sehr ruhig sein.
Gute nacht!
Gruß
Ge Ge

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
Noch kein Account? Hier anmelden.