Forum: Mikrocontroller und Digitale Elektronik Wer kennt sich mit string.h aus?


von Marcel K. (viewer)


Lesenswert?

Hallo zusammen,

Ich bin dabei mein MC35T mit dem ATmega16 auszulesen. Ankommende Daten 
zeige ich auf einem LCD- Display an.
Wenn ich dem Befehl zum senden eines Telfonbucheintrags abschicke, 
bekomme ich ein String mit den geforderten Daten. Soweit klappt das 
auch. Jetzt weiß ich, dass sowohl der Name, als auch die Nummer in 
Anführungszeichen <“> stehen. Ich merke mir, während das Array gefüllt 
wird, wo die 4 Anführungszeichen stehen. Wenn die Übertragung fertig 
ist, fülle ich die zwei Strings „name“ und „nummer“. Also habe ich eine 
Funktion geschrieben die sieht so aus:


void get_from_mc35t()
{
  U8 i = 0;
  temp[zaehler] = uart_getchar(); // in temp kommt das aktuelle 
empfangene Zeichen

      // hier wird das vierte Array-Platz gespeichert in dem das erste
      // < " > platziert ist
      if((temp[zaehler] == '"') &&(anf_zeich3 != 0)&&(anf_zeich4 == 0))
        {
          anf_zeich4 = zaehler;
        }

      // hier wird das dritte Array-Platz gespeichert in dem das erste
      // < " > platziert ist
      if((temp[zaehler] == '"') &&(anf_zeich2 != 0)&&(anf_zeich3 == 0))
        {
          anf_zeich3 = zaehler;
        }

      // hier wird das zweite Array-Platz gespeichert in dem das erste
      // < " > platziert ist
      if((temp[zaehler] == '"') &&(anf_zeich1 != 0)&&(anf_zeich2 == 0))
        {
          anf_zeich2 = zaehler;
        }

      // hier wird der erste Array-Platz gespeichert in dem das erste
      // < " > platziert ist
      if((temp[zaehler] == '"') &&(anf_zeich1 == 0))
        {
          anf_zeich1 = zaehler;
        }


      ///// Anfang der Auswertung nach empfangen des OK[CR][LF]
      if((temp[zaehler] == LF) && (temp[zaehler-1]== CR) && 
(temp[zaehler-2]== 'K') && (temp[zaehler-3] == 'O'))
      {
        lcd_clear();



        for(i = 0; i< (anf_zeich2 - anf_zeich1 -1); i++)
          {
            eintrag.nummer[i] = temp[anf_zeich1 +1 +i];
           }
        eintrag.name[i+2] = 0; // Am Ende noch eine Null dran hängen

        // hier wird vom dritten bis zum vierten < " > der Name in das 
Array
        // geschrieben
        for(i = 0; i< (anf_zeich4 - anf_zeich3 -1); i++)
          {
            eintrag.name[i] = temp[anf_zeich3 +1 +i];
           }
        eintrag.nummer[i+2] = 0; // Am Ende noch eine Null dran hängen


        lcd_gotoxy(1,1);
        lcd_text("Name:");
        lcd_gotoxy(1,2);
        lcd_text(eintrag.name);
        lcd_gotoxy(1,3);
        lcd_text("Nummer:");
        lcd_gotoxy(1,4);
        lcd_text(eintrag.nummer);

        i = 0;
        zaehler = 0;
        anf_zeich1 = 0;
        anf_zeich2 = 0;
        anf_zeich3 = 0;
        anf_zeich4 = 0;
      }  ///// Ende der Auswertung nach empfangen des OK[CR][LF]

      else // bezieht sich auf das "if" der Auswertung OK[CR][LF]
      {
        zaehler++;
      }


}// Ende get_from_mc35t()


Ich weiß, der Aufruf:
eintrag.nummer[i+2] = 0;
Sieht komisch aus, aber nur so geht das ganze.
Das ganze funktioniert eigentlich ganz gut. Allerdings nur so lange bis 
ich z.B. einen Namen mit 15 Zeichen gelesen habe, und dann einen mit nur 
10. Dann steht im String noch der Rest vom letzten. (der ganze Rest)

Jetzt ist meine Frage ob es bei den vielen Stingfunktionen nicht eine 
gibt, die mir dabei etwas mehr helfen könnte wie das zählen der 
Anführungszeichen. Ich habe zwar schon im Internet gesucht, allerdings 
gibt es nie Beispiele dazu.

Hat von euch jemand eine Idee????
Oder gibt es eine hilfreiche Internet- Seite??

Danke schon mal für eure Hilfe…
Grüße,
Marcel

von Durchblicker (Gast)


Lesenswert?

Ich finde, die Nullterminierung ist vertauscht für name und nummer. Da 
hast Du nen Dreher drin.

von Marcel K. (viewer)


Lesenswert?

Oh je, du hast recht!!!!!
Da habe ich vor lauter Bäumen den Wald nicht mehr gesehen!!!!

Aber leider geht es so immer noch nicht :o(

von Durchblicker (Gast)


Lesenswert?

Hier ein anderer Denkanstoss, ganz ohne sring.h

#define WAITNAME    0
#define READNAME    1
#define WAITNUMMER  2
#define READNUMMER  3
#define WAIT_O      4
#define WAIT_K      5
#define WAIT_CR     6
#define WAIT_LF     7

char Name[40];
char Nummer[40];
byte Cnt;
char Char = uart_getchar();
switch (State)
{
case WAITMAME:
    if (Char != '\"')
        break;
    State = READNAME;
    Cnt = 0;
    break;
case READNAME:
    if (Char != '\"')
    {
        Name[Cnt++] = Char;
        break;
    }
    State = WAITNUMMER;
    break;
case WAITNUMMER:
    if (Char != '\"')
        break;
    State = READNAME;
    Cnt = 0;
    break;
case READNUMMER:
    if (Char != '\"')
    {
        Name[Cnt++] = Char;
        break;
    }
    State = WAIT_O;
    break;
case WAIT_O:
    State = Char == 'O' ? WAIT_K : WAIT_NAME;
    break;
case WAIT_K:
    State = Char == 'K' ? WAIT_CR : WAIT_NAME;
    break;
case WAIT_CR:
    State = Char == '\r' ? WAIT_LF : WAIT_NAME;
    break;
case WAIT_LF:
    State = WAIT_NAME;
    if (Char == '\n')
        // Fertig, Datenverarbeitung
    break;
}

von Marcel K. (viewer)


Lesenswert?

Hallo  Durchblicker,

hmmm, ich bin noch kein all zu gutern Programmierer!!! Da brauche ich 
erst mal ne weile bis ich deinen Code richtig verstehe.

Aber auf jeden Fall mal vielen Dank für deinen Denkanstoss.

Ich gehe mal davon aus das "State" eine globale Variable ist!!



ich könnte für die Anzeige also noch schreiben:

#define WRITE_LCD     8



und dann unten:

case WAIT_LF:
    State = WRITE_LCD;
    if (Char == '\n')
    break;

case WRITE_LCD:
    State = WAIT_NAME;
    if (Char == '\n')
        // Fertig, Datenverarbeitung
        ///// Ausgabe auf dem LCD !!!
    break;



ist das so richtig??

Grüße Marcel

von Durchblicker (Gast)


Lesenswert?

Ja genau. Ausserdem habe ich die Nullterminierung vergessen, und bei 
READNUMMER hab ich in Name reingespeichert... :

case READNAME:
    if (Char != '\"')
    {
        Name[Cnt++] = Char;
        break;
    }
    Name[Cnt] = 0;
    State = WAITNUMMER;
    break;

case READNUMMER:
    if (Char != '\"')
    {
        Nummer[Cnt++] = Char;
        break;
    }
    Nummer[Cnt] = 0;
    State = WAIT_O;
    break;

Was bei Deinem Code schiefläuft, weiss ich allerdings auch nicht...

von Marcel K. (viewer)


Lesenswert?

@ Durchblicker,

so jetzt geht's endlich mit deinem "Denkanstoss" :o))

Es hat die ganze Zeit bei mir nicht funktioniert da ich einen Denfehler 
drin hatte.

1. Mann epfängt nicht automatisch nach dem letzten  "  das  OK\n\r . Das 
heißt die Funktion für  \n  und  \r  mußte hier so geschrieben werden 
wie bei dem ".

2. Man muss gleich beim  \r  auf das LCD geschrieben werden. Man kann 
nicht in  \r  schreiben: Status = WRITE_LCD da  \r  ja das letzte 
empfangene Zeichen ist und so die Funktion nicht mehr aufgerufe wird.

Wie gesagt, jetzt klappt das ganze aber hervorragend.

Viele Dank für deinen klasse Tip!!!!

Schönen Sonntag Abend noch und Grüße,

Marcel

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.