Forum: Compiler & IDEs [C] Char Array an Funktion übergeben


von Jan H. (jhnet)


Lesenswert?

Moin,

ich habe eine Methode die mit einem String aufgerufen werden soll, dann 
eine Checksume dranhängt und das ganze per UART von PeterFleury 
versendet.
Das sieht so aus:
1
static char calculate_checksum(char data[]) {
2
    char checksum = 0x00;
3
    for (uint8_t i = 0; i < strlen(data); i++) {
4
        checksum ^= data[i];
5
    }
6
    return checksum;
7
}
8
void send_uart_message(char message[]) {
9
    char checksum = calculate_checksum(message);
10
    char buffer[100];
11
    strcpy(buffer, "$");
12
    strcat(buffer, message);
13
    strcat(buffer, "*");
14
    char checksum_string[2];
15
    sprintf(checksum_string, "%02X", checksum);
16
    strcat(buffer, checksum_string);
17
    strcat(buffer, "\r\n");
18
    uart_puts(buffer);
19
}

Das ganze funktioniert nun, wenn ich es mit
1
send_uart_message("ABC");
aufrufe, ich möchte aber eigentlich soetwas machen, was aber zu einem 
Dauer-Reset führt:
1
char message[120];
2
sprintf(message, "CMP,%d,%d,%d,%d,%d,%d,%d,%d,%d", compass.yaw, compass.pitch,compass.roll, compass.acc_x, compass.acc_y, compass.acc_z,compass.mag_x,compass.mag_y,compass.mag_z);
3
send_uart_message(message);

Wie kann ich das Problem beheben ?
Danke im Voraus !

von Peter II (Gast)


Lesenswert?

Jan H. schrieb:
> char checksum_string[2];
> sprintf(checksum_string, "%02X", checksum);

dein Checksum_string ist zu kurz, checksum kann ja scheinbar bis 255 
werden. Dazu kommt noch das 0 Byte. Also sollte er mindestens 4byte lang 
sein.


> for (uint8_t i = 0; i < strlen(data); i++) {
ist etwas ungünstig, im Zweifelsfall wird stündig strlen aufgerufen.

for( uint8_t i = 0; data[i]; i++) {

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter II schrieb:
> dein Checksum_string ist zu kurz, checksum kann ja scheinbar bis 255
> werden. Dazu kommt noch das 0 Byte. Also sollte er mindestens 4byte lang
> sein.

Drei reichen bei hexadezimaler Darstellung. Aber drei müssen es schon 
sein.

von Peter II (Gast)


Lesenswert?

ausßerdem ist ist überhaupt nicht notwendig den string komplett 
zusammenzubauen, kostet nur zeit uns stack.
1
void send_uart_message(char message[]) {
2
    char checksum = calculate_checksum(message);
3
    char checksum_string[3];
4
    sprintf(checksum_string, "%02X", checksum);
5
6
    uart_puts("$");
7
    uart_puts("message");
8
    uart_puts("*");
9
    uart_puts( checksum_string );
10
    uart_puts( "\r\n");
11
}

sollte das gleiche machen, aber etwas weniger speicher brauchen.

von Jan H. (jhnet)


Lesenswert?

Jo danke nun funzt es, an "\0" hätte ich ja mal denken können -.-
Wundert mich nur, dass es mit "ABC" inkl. Checksumme funktioniert hat.


Peter II schrieb:
> ausßerdem ist ist überhaupt nicht notwendig den string komplett
> zusammenzubauen, kostet nur zeit uns stack.

> sollte das gleiche machen, aber etwas weniger speicher brauchen.


Jo, wo du es sagst...Warum eigentlich nicht !

von Karl H. (kbuchegg)


Lesenswert?

Und die Variable i in der Checksum Funktion braucht auch keiner
1
static char calculate_checksum(char data[]) {
2
    char checksum = 0x00;
3
4
    while( *data )
5
      checksum ^= *data++;
6
    }
7
8
    return checksum;
9
}

womit du ganz nebenbei die Beschränkung auf Strings der Maximallänge von 
255 Character losgeworden bist.

von Karl H. (kbuchegg)


Lesenswert?

Jan H. schrieb:

> Wundert mich nur, dass es mit "ABC" inkl. Checksumme funktioniert hat.

Das dumme an undefiniertem Verhalten ist, das alles mögliche passieren 
kann. Inklusive dem Verhalten, welches du erwartet hast.
Das bedeutet allerdings nicht, dass es deshalb in Ordnung wäre. 
Fehlerhaft ist fehlerhaft, selbst wenn zufällig das richtige rauskommt, 
weil du zufälig gerade irgendein momentan nicht benutztes Byte im 
Speicher niedergebügelt hast. Bei der nächsten Programmänderung oder 
-erweiterung kann das alles schon wieder ganz anders aussehen.

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.