sscanf liest ersten parameter nicht

OP #7420826
Lesenswert?

Hallo,

mit sscanf(STM32) will ich mehrere Parameter einlesen, das Problem ist dass er den ersten offensichtlich nicht einliest und der Parameter ist Null, sollte aber 1 sein. Die nachfolgenden werden problemlos eingelesen.

Woran kann das liegen?

Vielen Dank, Grüße, Seppel


Gesendeter String: "PARAM_POS 1 2 33.3"


Code:

1
uint16_t axis = 0U;
2
uint16_t iter = 0U;
3
float parameter = 0.0;
4

5
#include <string.h>
6

7
if (strncmp((const char *)usbRxBuffer,"PARAM_POS",9)==0U)
8
{
9
  sscanf(&usbRxBuffer[10], "%u %u %f", &axis, &iter, &parameter);
10
  SensorPosSetParam(axis,iter,parameter);
11
}

Ergebnis, axis wird nicht eingelesen, aber warum?:

usbRxBuffer = PARAM_POS 1 2 33.3\0\0......

axis = 0

iter = 2

param = 33.2999992

OP #7420834
Lesenswert?

Clemens L. schrieb:

%u ist unsigned int.

Für uint16_t brauchst du so etwas:#include <inttypes.h> sscanf(&buffer[10], "%"PRIU16" %"PRIU16" %f", &...);

Hallo,

könntest Du bitte den Code vervollständigen und mir erklären warum das mit uint16_t wie auch uint32_t nicht funktioniert?

Ich denke dass ich nicht der einzige bin der darüber stolpert, da sind vollständige Posts, mit funktionalem Code und Erklärung sinnvoll. Auch die innen liegenden Anführungszeichen, was tun die?

Vielen Dank, Grüße Seppel

#7420850
Lesenswert?

der Code funktioniert wenn ich den auf online gdb eingebe:

https://onlinegdb.com/nD89zYOS1D

1
#include <stdio.h>
2
#include <stdint.h>
3

4
const char usbRxBuffer[] = "PARAM_POS 1 2 33.3";
5

6
int main()
7
{
8
    printf("Hello World");
9
    
10
    uint16_t axis = 0U;
11
    uint16_t iter = 0U;
12
    float parameter = 0.0;
13

14
    #include <string.h>
15

16
    if (strncmp((const char *)usbRxBuffer,"PARAM_POS",9)==0U)
17
    {
18
        sscanf(&usbRxBuffer[10], "%u %u %f", &axis, &iter, &parameter);
19
        printf("result: %d %d %f", axis, iter, parameter);
20
    }
21

22

23
    return 0;
24
}

Bei uint16_t zwar mit Warnung, aber Ergebnis ist korrekt.

da würde ich davon ausgehen das der Inhalt von usbRxBuffer doch nicht so ist wie gedacht. Was sagt der Debugger? Oder ein printf vom usbRxBuffer?

#7420879
Lesenswert?

Clemens L. schrieb:

%u ist unsigned int.

Für uint16_t brauchst du so etwas: #include <inttypes.h> sscanf(&buffer[10], "%"PRIU16" %"PRIU16" %f", &...);

Nicht PRIU16, sondern SCNu16. PRI -> printf-Familie, SCN -> scanf-Familie. Außerdem würde ich da Leerzeichen drumherum machen. In C ist das zwar nicht unbedingt nötig, aber in C++ bekommt man ohne eine Fehlermeldung.

Seppel V. schrieb:

könntest Du bitte den Code vervollständigen und mir erklären warum das mit uint16_t wie auch uint32_t nicht funktioniert?

Weil die Größe nicht stimmt, zumindset bei uin16_t. %u ist ist für unsigned int, der auf einem ARM normalerweise 32 Bit ist. Du übergibst sscanf einen Zeiger auf einen 16-Bit-Wert, aber sscanf versucht entsprechend deiner Angabe, von dort stattdessen 32 Bit zu lesen, was natürlich falsch ist. Für die typedefs aus stdint.h wie uint16_t gibt es entsprechende Makros, die den richtigen Format-Specifier für den jeweiligen Typen bereitstellen. Statt also "%u" musst du "%" SCNu16 schreiben, um den richtigen Format-Specifier für uint16_t in scanf zu bekommen.

#7421010
Lesenswert?

nicht portabel, aber auf dem STM32 funktioniert das auch:

1
  uint16_t axis = 0U;
2
  uint16_t iter = 0U;
3
  float parameter = 0.0f;
4

5
  if (strncmp((const char *)usbRxBuffer,"PARAM_POS",9)==0U)
6
  {
7
      sscanf(&usbRxBuffer[10], "%hu %hu %f", &axis, &iter, &parameter);
8
  }

lässt man das h weg, dann schreibt sscanf Variablen auf dem Stack kaputt.

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