Forum: Compiler & IDEs Ausgabe mit dtostrf


von Jürgen H. (jhaerig)


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:
1
strom-Array: 16.16 
2
-> Char-Werte im temp-Array: (1,6,.,1,6, )
3
strom-Array: 08.08
4
-> 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.
1
double strom[] = {16.16,14.14,12.12,10.10,08.08,06.06,04.04,02.02};
2
char out_buffer[60];
3
char temp[6];
4
int a,d,c;
5
int main(void)
6
{
7
for(a=0;a<9;a++)
8
{
9
  dtostrf(strom[a],2,2,temp);   //stromwert, als char-array umwandeln
10
  temp[6] = 0x20;      //leerzeichen
11
  for(d=0;d<6;d++)
12
  {
13
    out_buffer[c+d] = temp[d];  //einzelne char werte in out_buffer schreiben
14
  }
15
  c=c+6;
16
}
17
while(1);
18
}

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

von der mechatroniker (Gast)


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.

von Jürgen H. (jhaerig)


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

von Bobby (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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
1
  char tmp[10];
2
  double a = 8.23;
3
4
  sprintf( tmp, "%6.3f", a );

von Jürgen H. (jhaerig)


Lesenswert?

Gut.

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

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.

von Karl H. (kbuchegg)


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:
1
  char buffer[20];
2
3
  for( i = 0; i < 9; ++i ) {
4
    sprintf( buffer, "%5.2f", strom[i];
5
    strcat( out_buffer, buffer );
6
7
    if( i != 9 )
8
      strcat( out_buffer, " " );
9
  }

(out_buffer muss bei Eintritt in die Funktion einen korrekten
String enthalten. Wenn diese Ausgabe mit einem leeren String
anfangen soll, dann sicherheitshalber so:
1
  char buffer[20];
2
3
  out_buffer[0] = '\0';
4
5
  for( i = 0; i < 9; ++i ) {
6
    sprintf( buffer, "%5.2f", strom[i];
7
    ....


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

von Jürgen H. (jhaerig)


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:
1
int main(void)
2
{
3
    char str[20];
4
    int len;
5
  int zahl=45;
6
  double test = 100.01;
7
8
    len = snprintf(str, 25, "%s %i %d", "hello world", zahl, test);
9
    printf("%s\n", str);
10
while(1);
11
}

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

von Karl H. (kbuchegg)


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#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio

von Jürgen H. (jhaerig)


Lesenswert?

verneig

mein retter! *yay!*

danke :)

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.