Code funktioniert- Verbesserungsvorschlag?

Gast #3443917
Hallo!

Ich möchte, dass der Controller die Werte eines Strings einem Variablen- 
Array korrekt zuweist.

Der String setzt sich aus Teistrings zusammen, die mit Semikolon 
getrennt sind. Ein Teilstring ist mit Doppelpunkt getrennt.

Stringbeispiel: 1:54;3:23;8:45

Daraus soll folgen, dass
receive_value[1] 54,
receive_value[3] 23 und
receive_value[8] 45 annimmt.

Mein Code dazu funktioniert, allerdings habe ich das Gefühl dass der 
ziemlich aufgebläht ist- Stringfunktionen sollen ja recht mühsam sein. 
Ich weiss aber nicht wie ich ihn optimieren kann. Weiß wer Rat?
1
char receive_string[20][20];
2
char receive_value[20];
3
char temp_string[20];
4

5
void readout_string(void)
6
{  
7
  volatile unsigned char *ptr;
8
  int i = 0;
9
  int k = 0;
10
  int l = 0;
11
  ptr = strtok(uart0_string, ";");
12

13
  while(ptr != NULL) 
14
  {
15
    strcpy(receive_string[i], ptr);
16
    ptr = strtok(NULL, ";");
17
    i++;
18
  }
19
  
20
  for (k = 0; k < i; k++)
21
  {
22
    ptr = strtok(receive_string[k], ":");
23
    strcpy(temp_string, ptr);
24
    l = atoi(temp_string);
25
    ptr = strtok(NULL, ":");    
26
    strcpy(temp_string, ptr);    
27
    receive_value[l] = atoi(ptr);
28
  }  
29
}
#3443967
mach alles in einem Aufwasch, ohne zuerst die Teilstrings in ein 
getrenntes String Array umzukopieren.

Du darfst bei strtok durchaus auch abwechselnd verschiedene Trenner 
benutzen
1
...
2

3
  ptr = strtok( uart_string, ":" );
4
  while( ptr )
5
  {
6
     // jetzt haben wir den "Index" -> in eine Zahlumwandeln
7
     index = atoi( ptr );
8
     ptr = strtok( NULL, ";" );
9
     if( ptr )
10
     {
11
       // und jetzte auch noch den zugehörigen Wert
12
       wert = atoi( ptr );
13
       receive_value[index] = wert;
14
     }
15

16
     ptr = strtok( NULL, ":" );
17
   }
18
 }


sieht doch schon gleich viel kürzer aus und ist auch sicherer, weil du 
nicht gefahr läufst, bei den strcpy die Zielstrings zu überlaufen.
Und 400 Bytes SRAM sparst du obendrein :-)
#3443983
Ene kleine Fehlerquelle:
1
i = atoi(ein_string_von_aussen);
2
foo[i] = atoi(ein_anderer_string);
verlagert die Verantwortung für das Einhalten der Arraygrenzen auf das 
Programm, das die Strings sendet. Geht da irgendetwas daneben, wird 
irgendwo wild in den RAM geschrieben.
Gast #3443988
nur mit strtol

Stephan schrieb:
> Stringbeispiel: 1:54;3:23;8:45
>
> Daraus soll folgen, dass
> receive_value[1] 54,
> receive_value[3] 23 und
> receive_value[8] 45 annimmt.
1
unsigned char
2
parse(char*str) { unsigned char ret;
3
 do {
4
     idx=strtol(str,&str,0); // oder 10 fuer dec
5
     while(*str++==':') {
6
       val=strtol(str,&str,0); // oder 10 fuer dec
7
       if(idx>=0&&idx<sizeof(receive_value)/sizeof(receive_value[0]))
8
         receive_value[idx++]=val,ret++;
9
     }
10
    } while(*str++==';');
11
 return ret;
12
}
> Stringbeispiel: 1:54:33:44;13:23;8:45
>
> Daraus soll folgen, dass
> receive_value[1] 54,
> receive_value[2] 33,
> receive_value[3] 44,
> receive_value[13] 23 und
> receive_value[8] 45 annimmt.
Gast #3443998
chris schrieb:
> unsigned char
> parse(char*str) { unsigned char ret;
>  do {
>      idx=strtol(str,&str,0); // oder 10 fuer dec
>      while(*str++==':') {
>        val=strtol(str,&str,0); // oder 10 fuer dec
>        if(idx>=0&&idx<sizeof(receive_value)/sizeof(receive_value[0]))
>          receive_value[idx++]=val,ret++;
>      }
>     } while(*str++==';');
>  return ret;
> }

Da muss man erstmal hinterkommen.....
#3444012
Stephan schrieb:
> chris schrieb:
>> unsigned char
>> parse(char*str) { unsigned char ret;
>>  do {
>>      idx=strtol(str,&str,0); // oder 10 fuer dec
>>      while(*str++==':') {
>>        val=strtol(str,&str,0); // oder 10 fuer dec
>>        if(idx>=0&&idx<sizeof(receive_value)/sizeof(receive_value[0]))
>>          receive_value[idx++]=val,ret++;
>>      }
>>     } while(*str++==';');
>>  return ret;
>> }
>
> Da muss man erstmal hinterkommen.....

halb so wild.
strtol vereint mehr oder weniger ein atoi und das strtok in einer 
Funktion.

atoi würde selbsttätig mit dem Konsumieren des Strings aufhören, sobald 
etwas nicht mehr zur Zahl gehört.
D.h. wirfst du atoi das hier vor
"123:56"
dann konsumiert atoi alles bis zum ':'.
Soweit so gut. Nur weißt du nicht, wo im String diese Aufhören 
stattfindet, so dass du das nächste atoi 1 Zeichen dahinter ansetzen 
könntest.

und genau da kommt strtol ins Spiel. Es liefert dir genau diese 
Position, bis zu der es aus dem String Zeichen konsumiert hat. Mit 
dieser Position (nach Prüfung natürlich) kannst du dann den nächsten 
strtol dahinter ansetzen, der wieder alles was nach Zahl aussieht 
konsumiert und dir mit dem Pointer bekannt gibt, wo dieses Ende war. 
Woraufhin du dort den nächsten strtol ansetzt, etc. etc.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.