sprintf ersatz? ( c code )

Gast #4247379
Lesenswert?

hi

gibt es einen vernünftigen sprintf ersatz für einen einzelnen parameter 
als unsigned long ?

- ohne malloc
- ohne stdarg.h

wie macht ihr das im embedded design?


da war ich schon:
1
int v = -10093;    //Integer value to convert to string
2

3
  char buffer[64];
4
  int nI = 0;
5

6
  if(v < 0)
7
  {
8
    buffer[nI++] = '-';
9
    v = -v;
10
  }
11

12
  if(v)
13
  {
14
    BOOL bNoLeadingZeros = TRUE;
15
    static int pMods[] = {1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
16
    for(int i = 0; i < sizeof(pMods) / sizeof(pMods[0]); i++)
17
    {
18
      int d = v / pMods[i];
19
      if(d || !bNoLeadingZeros)
20
      {
21
        bNoLeadingZeros = FALSE;
22
        buffer[nI++] = '0' + d;
23
        v &#37;= pMods[i];
24
      }
25
    }
26
  }
27
  else
28
    buffer[nI++] = '0';
29

30
  buffer[nI] = 0;
31

32
  //'buffer' now contains the string version of 'v'


auch da:
braucht die libgcc
das ist schlecht

1
char *itoa(int num)
2

3
{
4
static char buff[20] = {};
5
int i = 0, temp_num = num, length = 0;
6
char *string = buff;
7
if(num >= 0) {
8
// count how many characters in the number
9
while(temp_num) {
10
temp_num /= 10;
11
length++;
12
}
13
// assign the number to the buffer starting at the end of the 
14
// number and going to the begining since we are doing the
15
// integer to character conversion on the last number in the
16
// sequence
17
for(i = 0; i < length; i++) {
18
buff[(length-1)-i] = '0' + (num % 10);
19
num /= 10;
20
}
21
buff[i] = '\0'; // can't forget the null byte to properly end our string
22
}
23
else
24
return "Unsupported Number";
25
return string;
26
}


und auch da

https://github.com/mludvig/mini-printf
Fehler: "signal caught in writing whirl file"

und chan werde ich noch ansehen:

http://elm-chan.org/fsw/strf/xprintf.html
Gast #4247404
Lesenswert?

sprint und Konsorten brauchen nur deshalb so viel Platz, weil es 
sogenannte eierlegende Wollmilchsäue sind.
Geschrieben unter der Maxime: "Darf‘s noch ein bissel mehr sein"?
Würde mich, beim Betrachten der Optionen, nicht wundern, wenn die auch 
kochen und backen können.

Allerdings gibt es auch oft Leute die keinen Einheitsbrei auszugeben 
haben, was in Umkehr der obigen Aussage ein Vorteil wäre.

Also des einen Freud...

In diesem Konflikt würde ich Dir empfehlen: Sag doch mal was Du 
(ausgeben)willst!
Gast #4247471
Lesenswert?

>>Sprintf sollte man sofort vergessen. Viel zu klotzig.

Warum? Wenn genug Platz das ist, kann man es doch auch benutzen.
Und man muss sich verdammt anstrengen, den Speicher der modernen 
Prozessoren komplett zu belegen.

Ich würde sprintf benutzen, um mich lieber den wichtigen Problemen 
widmen.
Persönliche Seite #4247530
Lesenswert?

c schüler schrieb:
> int d = v / pMods[i];
>
> braucht die libgcc

Das wundert duch jetzt nicht wirklich...?  Du dividiert auf einer 
Hardware, die kein DIV-Befehl hat, durch einen unbekannten Divisor.

Evtl. reisst da -O3 -funroll-loops -funroll-all-loops was aus, aber auf 
deep embedded ist das auch nicht wirklich prickelnd.  Dann doch lieber 
so (C99):
1
#include <stdint.h>
2
#include <stdbool.h>
3

4
#if defined (__GNUC__) && defined (__AVR__) && defined (__FLASH)
5
#define flash __flash
6
#else
7
#define flash // empty
8
#endif // avr-gcc has __flash
9

10
// Wandelt N in eine ASCII-Dezimalzahl um. Die Darstellung wird
11
// mit abschliessender '\0' als Stringende nach *STR geschrieben.
12
// Return: Adresse der abschliessenden '\0'.
13

14
char* u32_to_string (char *str, uint32_t n)
15
{
16
    static const flash uint32_t pows10[] = 
17
    {
18
        1e8, 1e7, 1e6, 1e5, 1e4, 1e3, 1e2, 1e1
19
    };
20

21
    const flash uint32_t *p = pows10;
22

23
#if defined (__OPTIMIZE__) && !defined (__OPTIMIZE_SIZE__)
24
    if (n < 100000)
25
        p += 4; // skip 10^8 ... 10^5
26
#endif
27

28
    uint32_t pow10;
29
    bool nonzero = false;
30

31
    do
32
    {
33
        pow10 = *p++;
34

35
        char c = '0';
36
        
37
        while (n >= pow10)
38
        {
39
            n -= pow10;
40
            nonzero = true;
41
            c++;
42
        }
43
            
44
        if (nonzero)
45
            *str++ = c;
46
            
47
    } while (! (pow10 & 2)); // pow10 != 10
48
    
49
    // Einer
50
    *str++ = n + '0';
51
    *str = '\0';
52
    
53
    return str;
54
}
Gast #4248936
Lesenswert?

danke an alle!
ich habe xprintf mal mehr oder weniger jetzt auch hier in dem fall 
probiert und es läuft damit mal vorerst. der ansatz von Johann werde ich 
mal näher ansehen, danke!

@PittyJ
ich widme mich gerade dem problem "sprintf" :)

der thread gab mir auch sehr viel hintergrund hilfe:
Beitrag "sprintf am STM32F072"

um auf bestimmte compiler flaggs zu kommen.
ich brauche kein float, nur max unsigned long.

solved!

lg
;-)

@Daniel:
ich hatte xprintf noch gar nicht bemerkt im sd einsatz,
nur immer schön altbacken sprintf / printf.
Gast #4248949
Lesenswert?

Johann L. schrieb:
> c schüler schrieb:

>> int d = v / pMods[i];
>>
>> braucht die libgcc
>
> Das wundert duch jetzt nicht wirklich...?  Du dividiert auf einer
> Hardware, die kein DIV-Befehl hat, durch einen unbekannten Divisor.

wenn ich jemals nur 50 prozent wissen erreiche um eine derartig - mitten 
ins schwarze - treffende aussage machen zu können, wäre ich zufrieden.
1+

es wurde alles gestrippt was es zu strippen gilt(gibt).
jetzt wird langsam aufgebaut, was wirklich nur gebraucht wird und
auf was verzichtet werden kann.


nicht böse sein Axel:

Axel S. schrieb:
> c schüler schrieb:
>> auch da:
>> braucht die libgcc
>
> Verstehe ich jetzt nicht. Wozu sollte diese itoa Implementierung
> libgcc benötigen? Ich sehe da nur Standard-C in Verwendung.


da sind welten dazwischen :)

danke Johann!

;-)
#4249325
Lesenswert?

c schüler schrieb:
> Johann L. schrieb:

>> Das wundert duch jetzt nicht wirklich...?  Du dividiert auf einer
>> Hardware, die kein DIV-Befehl hat, durch einen unbekannten Divisor.
>
> wenn ich jemals nur 50 prozent wissen erreiche um eine derartig - mitten
> ins schwarze - treffende aussage machen zu können, wäre ich zufrieden.

Naja, das war einfach gut geraten. Zumal du ja deine Zielarchitektur gar 
nicht genannt hattest.

> nicht böse sein Axel:
>
> Axel S. schrieb:
>> Verstehe ich jetzt nicht. Wozu sollte diese itoa Implementierung
>> libgcc benötigen? Ich sehe da nur Standard-C in Verwendung.
>
> da sind welten dazwischen :)

Du hättest ja auch ein bisschen mehr Input liefern können. Zum Beispiel 
was aus der libgcc da zu deinem Programm gelinkt wird. Und du hast 
auch immer noch nicht gesagt, warum das schlecht sein soll. Jedes 
C-Programm braucht Funktionen aus der C-Runtime. Das eine mehr, das 
andere weniger. Und wenn du eine arithmetische Operation verwendest, die 
auf der Zielarchitektur nicht inline erzeugt werden kann, dann 
bekommst du halt die entsprechende Funktion aus der Runtime dazugelinkt. 
Was denn sonst?
Gast #4249838
Lesenswert?

c schüler schrieb:
> gibt es einen vernünftigen sprintf ersatz für einen einzelnen parameter
> als unsigned long ?

Lade dir die Lernbetty hier aus dem Forun herunter und benutze davon 
conv.c - da hast du eigentlich alles, was du brauchst.

Und "JA" das hat hier auch schon jemand mit nem AVR benutzt, dieses 
Stückchen Quelle geht nicht nur für ARM.

Und noch ein Wort zu sprintf und Konsorten: Auf einem µC ist mir sowas 
auch viel zu klobig.

W.S.

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