www.mikrocontroller.net

Forum: Compiler & IDEs Ausgabe mit dtostrf


Autor: Jürgen Härig (jhaerig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich brauche eine Idee bei der Umwandlung von einem double-Wert in 
einzelne Char-Zeichen. Wie Ihr im unteren Code sehen könnt, hab ich die 
Funktion dtostrf schon gefunden und auch erfolgreich eingebunden.

ABER, sie tut nicht ganz genau, was ich will.

Ich will die Werte aus dem strom-Array eins zu eins ausgeben, also mit 
allen Nullstellen, auch vor der eigentlichen Zahl.

Im Moment schreibt mir dtostrf bei dem strom[4] Wert: 08.08, 8.08 ins 
out_buffer Array, aber ich hätte dort gerne 08.08 stehen. Ebenso ergeht 
allen Werten die eine Null voran führen.

Zudem verschieben sich die Werte im temp-Array, wenn eine Null vor dem 
Messwert steht nach vorn.
Bsp:
strom-Array: 16.16 
-> Char-Werte im temp-Array: (1,6,.,1,6, )
strom-Array: 08.08
-> Char-Werte im temp-Array: (8,.,0,8, ,,)

Kann mir da jemand einen Tipp geben, wie ich die Null-Stellen dort 
hinein bekomme? Wenn ich mal 00.00 im strom-Array habe, wird es auch 
keine Ausgabe geben, das ist unschön.

Danke Euch.
double strom[] = {16.16,14.14,12.12,10.10,08.08,06.06,04.04,02.02};
char out_buffer[60];
char temp[6];
int a,d,c;
int main(void)
{
for(a=0;a<9;a++)
{
  dtostrf(strom[a],2,2,temp);   //stromwert, als char-array umwandeln
  temp[6] = 0x20;      //leerzeichen
  for(d=0;d<6;d++)
  {
    out_buffer[c+d] = temp[d];  //einzelne char werte in out_buffer schreiben
  }
  c=c+6;
}
while(1);
}

PS: Boah.. "Your post seems to contain Spam: "***"." NUR weil eine 
Variable b hieß....! -.-

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf bietet mehr Möglichkeiten zur Zahlenformatierung, u.a. auch 
feste Anzahl Nachkommastellen; wie es vor dem Komma ausschaut, weiß ich 
jetzt net auswendig. Schau halt mal nach.

Autor: Jürgen Härig (jhaerig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf kenn ich nur in zusammenhang mit ausgaben auf der uart 
schnittstelle. das man damit %2.2i machen kann, ist mir bekannt.

kann man damit etwa auch arrays füllen?

mir geht es wirklich primär darum das out_buffer array mit den 
Messwerten zu füllen. später soll genau das array auf eine SD Karte 
schrieben werden

Autor: Bobby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann nimm sprintf.
Der erste Parameter ist die Array-Adresse,
das sollte also kein weiteres Problem sein.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen Härig wrote:
> sprintf kenn ich nur in zusammenhang mit ausgaben auf der uart
> schnittstelle.

sprintf (man beachte das führende 's') hat erst mal überhaupt nichts
mit der UART zu tun.
Die Aufgabe von sprintf ist es einen Text mithilfe des Formatstrings
zu formatieren, wobei die angegebenen Argumente an die entsprechenden
Stellen eingebaut werden, und das Ergebnis in einem Character
Array (welches natürlich groß genug sein muß) als String abzulegen.

Was du dann mit dem String weiter machst ist deine Sache und
kümmert den sprintf wenig.

> das man damit %2.2i machen kann, ist mir bekannt

dann weist du mehr als der Rest der C-Welt. Die Formatspezifizierung
'i' passt nicht zur Ausgabe eines Floating Point Wertes. Der Format-
specifier dafür wäre 'f'.
2.2 kann auch nicht stimmen. Die Zahl vor dem . ist die komplette
Anzahl der auszugebenden Stellen. Inklusive Voreizeichen und
Kommapunkt
Wenn du also eine Zahl haben willst in der Gestalt xx.yyy
(also 2 Vorkomma und 3 Nachkommastellen), dann brauchst du
dafür schon mindestens eine Feldbreite von 6. Und da ist ein
Vorzeichen noch gar nicht berücksichtigt
  char tmp[10];
  double a = 8.23;

  sprintf( tmp, "%6.3f", a );

Autor: Jürgen Härig (jhaerig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut.

Ich hab euren Rat befolgt und sprintf getestet.
  for(a=0;a<=8;a++)
  {
    //dtostrf(strom[a],2,2,temp);   //stromwert, als char-array umwandeln
    sprintf(temp,"%2.2f",strom[a]);
    for(d=0;d<5;d++)
    {
      out_buffer[c+d] = temp[d];  //einzelne char werte in out_buffer schreiben
    }
  out_buffer[c+b] = 0x20;
  c=c+6;
  }

Allerdings bekomme ich nun "müll" in das temp Array geschrieben.
Besser gesagt: 0x32 an Stelle [0], und 0x63 an Stelle [1].
Das hilft mir nicht sonderlich...

Wenn ich ein Array mit einem String über %s ausgeben lasse... kein 
Problem. Auch Int Zahlen, keine sache. Aber sobald ich double bzw. float 
Zahlen ausgeben lassen will, landen sinnfreie Werte im temp Array.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen Härig wrote:
> Gut.
>
> Ich hab euren Rat befolgt und sprintf getestet.
>
>   for(a=0;a<=8;a++)

Wenn ich so eine for Schleife sehe, läuten bei mir alle
Alarmglocken.

>   {
>     //dtostrf(strom[a],2,2,temp);   //stromwert, als char-array
> umwandeln
>     sprintf(temp,"%2.2f",strom[a]);

Da steht ja immer noch 2.2
Wie soll den eine komplette Ausgabe in 2 Zeichen passen, wenn der
Nachkommaanteil schon 2 Stellen verbraucht.

>     for(d=0;d<5;d++)
>     {
>       out_buffer[c+d] = temp[d];  //einzelne char werte in out_buffer
> schreiben
>     }

Du weist schon, dass die sprintf die Ausgabe als ganz normalern
String formatiert. Oder anders gefragt: Woher weist du eigentlich,
dass das immer 5 Buchstaben sind?

>   out_buffer[c+b] = 0x20;

Wenn du Leerzeichen meinst, dann schreibe auch Leerzeichen.
Kein Grund mit ASCII Codes um sich zu schmeissen:

   out_buffer[c+b] = ' ';

Die vorhergehende for-Schleife hatte als Schleifenvariable ein
d (wie Dora). Hier kommt jetzt plötzlich ein b (wie Berta) ins
Spiel. Wie das?

Warum nicht ganz einfach:
  char buffer[20];

  for( i = 0; i < 9; ++i ) {
    sprintf( buffer, "%5.2f", strom[i];
    strcat( out_buffer, buffer );

    if( i != 9 )
      strcat( out_buffer, " " );
  }


(out_buffer muss bei Eintritt in die Funktion einen korrekten
String enthalten. Wenn diese Ausgabe mit einem leeren String
anfangen soll, dann sicherheitshalber so:
  char buffer[20];

  out_buffer[0] = '\0';

  for( i = 0; i < 9; ++i ) {
    sprintf( buffer, "%5.2f", strom[i];
    ....


(und überprüfen, ob das auch wirklich 9 Strom-Werte oder doch
korrekterweise 8 sind - wegen der for-Schleife)

Autor: Jürgen Härig (jhaerig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:

>>     //dtostrf(strom[a],2,2,temp);   //stromwert, als char-array
>> umwandeln
>>     sprintf(temp,"%2.2f",strom[a]);
>
> Da steht ja immer noch 2.2
> Wie soll den eine komplette Ausgabe in 2 Zeichen passen, wenn der
> Nachkommaanteil schon 2 Stellen verbraucht.

stimmt. mein fehler


>>     for(d=0;d<5;d++)
>>     {
>>       out_buffer[c+d] = temp[d];  //einzelne char werte in out_buffer
>> schreiben
>>     }
>
> Du weist schon, dass die sprintf die Ausgabe als ganz normalern
> String formatiert. Oder anders gefragt: Woher weist du eigentlich,
> dass das immer 5 Buchstaben sind?

nope, bis zu dem zeitpunkt war mir das nicht bekannt.


>>   out_buffer[c+b] = 0x20;
>
> Wenn du Leerzeichen meinst, dann schreibe auch Leerzeichen.
> Kein Grund mit ASCII Codes um sich zu schmeissen:
>
>    out_buffer[c+b] = ' ';

schönheitsfehler :)


> Die vorhergehende for-Schleife hatte als Schleifenvariable ein
> d (wie Dora). Hier kommt jetzt plötzlich ein b (wie Berta) ins
> Spiel. Wie das?

ähm... das eine b (Berta) hab ich wohl übersehen, als ich alle b´s 
entfernen musste, da der foren-spam-filter keine [berta] variablen haben 
wollte.

die beispiele hab ich mit dem AVR Studio getestet.
aber anstatt des float (double) werts landen nicht einzelne chars im 
array, sondern 0x32 (leerzeichen) an den positionen mit einem 0x63 
(fragezeichen) an letzter position.

selbiges geschieht, wenn ich mit snprintf die ausgabe versuche:
int main(void)
{
    char str[20];
    int len;
  int zahl=45;
  double test = 100.01;

    len = snprintf(str, 25, "%s %i %d", "hello world", zahl, test);
    printf("%s\n", str);
while(1);
}

im array str ist alles lesbar, bis auf die ausgabe des double wertes, 
der ist komplett falsch.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen Härig wrote:

> die beispiele hab ich mit dem AVR Studio getestet.
> aber anstatt des float (double) werts landen nicht einzelne chars im
> array, sondern 0x32 (leerzeichen) an den positionen mit einem 0x63
> (fragezeichen) an letzter position.

Das Fragezeichen ist der Hinweis.

http://www.mikrocontroller.net/articles/FAQ#Aktivi...

Autor: Jürgen Härig (jhaerig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
verneig

mein retter! *yay!*

danke :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.