Frage zur sprintf-Fkt mit Variablen

Gast #2220865
Lesenswert?

Hallo,

ich möchte gerne die Formatierung der sprintf-Funktion über die Variable 
digits steuern
zB:
statt
sprintf(string,"%3d",value);

sprintf(string,"%"+digits+"d,value);
klappt nicht!

Wie mache ich es, dass "digits" in diesem Zusammenhang al0s Variable 
gesehen wird und den Zahlenwert ersetzt?
Gast #2220877
Lesenswert?

Ääh, hab die Variablen verwechselt. Also so:
1
char digits=(char)('0'+n);
Zeichenketten addieren geht nur mit AnsiString. Also erst schön mit 
strncat (oder so ähnlich) zusammenbasteln. Aah, fällt mir noch ein:
1
uint8_t n=9; // maximal!
2
formatString[]="%Xd";
3
formatString[1]=(char)('0'+n);
4
sprintf(string,formatString,value);
Das müsste auch gehen.
#2221203
Lesenswert?

Klaus Wachtler schrieb:
> @Jörg G.:
>
> wenigstens einer, der auch mal die man-page zu Formatstrings gelesen hat
> :-)


:-)

Und ehe es diese Möglichkeit gab, hat man sich halt daran erinnert, dass 
der Formatstring auch nur ein String ist. Es spricht also nichts 
dagegen, sich diesen ebenfalls mittels Programm generieren zu lassen
1
  char FormatString[10];
2

3
  sprintf( FormatString, "%%%dd", digits );
4
  sprintf( string, FormatString, value );


Aber mit dem * ist es natürlich eleganter, solange man nur eine Zahl 
ersetzen lassen will. Will man noch zusätzliche 'Optionen' in den 
Formatstring bei Bedarf einbauen (führende 0-en, Vorzeichen, etc.) dann 
ist die Generiermethode immer noch kein schlechter Weg.
Gast #2221432
Lesenswert?

Hallo,

ich hab nun folgendes getestet:
1
 
2
 char FormatString[10];
3

4
  sprintf( FormatString, "%%%dd", digits );
5
  sprintf( string, FormatString, value );

Bekomme vom Compiler aber leider folgende Fehlermeldung:

function argument #2 of type 'flash unsigned char[10]' is incompatible 
with required parameter of type 'flash unsigned char*'
Gast #2221454
Lesenswert?

Dort steht folgendes:


int sprintf(char *str, char flash *fmtstr [ , arg1, arg2, ...])
      this function is identical to printf except that the formatted 
text is placed in the null terminated character string str.
The function returns the number of outputed characters.
Gast #2221473
Lesenswert?

OK, hier ist sie

int printf(char flash *fmtstr [ , arg1, arg2, ...])


      outputs formatted text, using putchar, according to the format 
specifiers in the fmtstr string.
The format specifier string fmtstr is constant and must be located in 
FLASH memory.
The implementation of printf is a reduced version of the standard C 
function.
This was necessary due to the specific needs of an embedded system and 
because the full implementation would require a large amount of FLASH 
memory space.
The function returns the number of outputed characters.
...
Gast #2221510
Lesenswert?

Du musst, wie schon geschrieben, die Doku von printf anschauen. Die 
besteht nicht nur aus dem von Dir geposteten Text sondern auch aus der 
Beschreibung des Formatstrings.

Es ist zu prüfen ob dies hier:
>The implementation of printf is a reduced version of the standard C
>function.

evtl. auch bedeutet, das '*' nicht unterstützt wird.

Wenn '*' nicht unterstützt wird, dann musst Du eine eigene 
Ausgabefunktion bzw. Stringerstellungsfunktion basteln, die eine 
variable Anzahl Stellen ausgibt.
Gast #2221515
Lesenswert?

Irgendwie kommt mir das auch komisch vor.

>ich hab nun folgendes getestet:


> char FormatString[10];

>  sprintf( FormatString, "%%%dd", digits );
>  sprintf( string, FormatString, value );

>Bekomme vom Compiler aber leider folgende Fehlermeldung:

>function argument #2 of type 'flash unsigned char[10]' is incompatible
>with required parameter of type 'flash unsigned char*'

Auf welche Zeile genau bezieht sich die Fehlermeldung? Das einzige wo Du 
ein unsigned char[10] übergibst ist das erste printf. FormatString hat 
aber gar keinen Type-Modifier "flash". Ist das wirklich der 
Originaltext?
Gast #2221532
Lesenswert?

>In der Doku steht doch eindeutig, daß der Format-String im Flash sein
>muss. Also werden keine dynamisch erzeugten Formatstrings unterstützt.

Hm. Das erklärt aber nicht, warum das hier:
1
sprintf( string, "%*d", digits, value );

nicht geht.
Persönliche Seite #2221537
Lesenswert?

Guru schrieb:
>>In der Doku steht doch eindeutig, daß der Format-String im Flash sein
>>muss. Also werden keine dynamisch erzeugten Formatstrings unterstützt.
>
> Hm. Das erklärt aber nicht, warum das hier:
>
>
1
> sprintf( string, "%*d", digits, value );
2
>
>
> nicht geht.

Ak, ok. Das fällt im Zweifelsfalle fällt's unter "reduced version of the 
standard C function". ;-)
Gast #2222003
Lesenswert?

OK, dann programmier ich mir die Funktion selbst..

Hier erst mal der Code für die Integer-Ausgabe:
Die Übergabeparamter sind (int value, unsigned char digits)
[c]
unsigned char string[StringBufferSize];
unsigned char string_temp[StringBufferSize];
unsigned int digits_temp;
unsigned int i;


itoa(value, string_temp);

digits_temp = strlen(string_temp);

if(digits_temp < digits)
{
    for(i=0; i<((unsigned int)digits-digits_temp); i++)
    {
        strcat(string," ");
    }
}
strcat(string, string_temp);
[\c]

Dies funktioniert die meiste Zeit ganz gut, nur wenn manchmal stehen am 
Anfang des Strings noch alte Ergebnisse oder andere Zeichen.

Wie kann ich die beiden Arrays:
unsigned char string[StringBufferSize];
unsigned char string_temp[StringBufferSize];
bei der Deklaration initialisieren?

Seht ihr sonst im dem Code noch einen Fehler oder habt einen 
Verbesserungsvorschlag?
#2222005
Lesenswert?

An einer kompletten Funktion könnte man vielleicht Fehler sehen ....

Abgesehen davon, daß strcat() da vielleicht nicht besonders effizient 
ist.

Willst du die Leerzeichen links oder rechts angefügt haben?


Ggf. wäre es vielleicht sinnvoller, das Schreiben des Werts in einen 
String und das Auffüllen mit Leerzeichen auf eine gewünschte Länge 
(links oder rechts auffüllen) zu trrennen, sonst musst du das Auffüllen 
für int, unsigned int, short, float... jedesmal neu machen.
#2222009
Lesenswert?

1
#include <string.h>
2

3
// füllt einen String str links auf mindestens l_min Zeichen auf
4
// Achtung - keine Fehlerprüfungen!
5
// Der String muß groß genug sein (l_min+1).
6
// Rückgabe ist der String.
7
char *fill_l( char *str, size_t l_min, char fill_char )
8
{
9
  size_t l = strlen( str );
10
  if( l<l_min )
11
  {
12
    memmove( str+l_min-l, str, l+1 );
13
    memset( str, fill_char, l_min-l );
14
  }
15
  return str;
16
}
17

18
// füllt einen String str rechts auf mindestens l_min Zeichen auf
19
// Achtung - keine Fehlerprüfungen!
20
// Der String muß groß genug sein (l_min+1).
21
// Rückgabe ist der String.
22
char *fill_r( char *str, size_t l_min, char fill_char )
23
{
24
  size_t l = strlen( str );
25
  if( l<l_min )
26
  {
27
    memset( str+l, fill_char, l_min-l );
28
    str[l_min] = '\0'; // terminieren
29
  }
30
  return str;
31
}
32

33

34
#include <stdio.h>
35

36
int main( int nargs, char **args )
37
{
38
  char   puffer1[100] = "12";
39
  char   puffer2[100] = "12";
40

41
  printf( "<%s>\n", fill_l( puffer1, 4, ' ' ) );
42
  printf( "<%s>\n", fill_r( puffer2, 4, ' ' ) );
43

44
  return 0;
45
}
#2222080
Lesenswert?

PS:
Wenn es dann nur noch darum geht, eine int irgendwie in Textform zu 
bringen (12 -> "12"), dann ist sprintf() nicht das Mittel der Wahl. Denn 
sprintf() ist eine Monsterfunktion, die viel Code hat und nicht 
besonders schnell ist.
Besser nimmt man dann etwas wie itoa().

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