Code funktioniert- Verbesserungsvorschlag?

Gast #3443917
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren