?
Shinigami schrieb:
Moin Moin,
Wie kann ich wen ich mit printf einen int Wert ausgebe, zur besseren lesbarkeit großer Zahlen, unterteilungs Punkte setzen lassen?
Also das z.B nicht 105538654 sondern 105.538.654 angezeigt wird.
Vor einiger Zeit hatte ich ein ähnliches Problem. Vielleich hilfts ja:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <ctype.h>
int num_to_pic (char * dest, char * source, char * pic, int length)
{
int i,j,k,s_flag=0,z_flag;
j = length-1;
memset(dest, ' ', (size_t) length); // clear Destination field
// First pass initilizes the zero digits and decimalpont
z_flag = 0;
for (i = j;i >= 0;i--)
{
if (pic[i] == 'Z')
{
dest[i] = '0'; // Initialize dest with zero if "Z" is defined
if (z_flag == 0)
z_flag = -1;
}
else
{
if (pic[i] != '#' && pic[i] != 'c' && pic[i] != 'd')
{
if (z_flag == -1) // First zero pic alrady found?
{
dest[i] = pic[i]; // decimalpoint or -comma
z_flag = 1; // Flag comma now set
}
}
}
}
// Second pass completes the string
for (i = j;i >= 0;i--)
{
if (isdigit(source[i])) // Numeric field
{
if ((pic[j] == '#') || (pic[j] == 'Z')) // Pic numeric?
{
dest[j] = source[i]; // copy digit
j--;
}
else
{
if (pic[j] == 'd' || pic[j] == 'c') // Debitor, creditor?
{
s_flag = -1; // yes --> numeric value without sign
j--;
if ((pic[j] == '#') || (pic[j] == 'Z')) // next entry numeric pic?
{
dest[j] = source[i]; // yes --> copy digit
j--;
}
else
{
return 1; // No --> Invalid Picture String
}
}
else
{
dest[j] = pic[j]; // copy Pic
j--;
if ((pic[j] == '#') || (pic[j] == 'Z')) // next entry numeric pic?
{
dest[j] = source[i]; // yes --> copy digit
j--;
}
else
{
return 1; // No --> Invalid Picture String
}
}
}
}
else
{
if ((source[i] == '+' || source[i] == '-') && (s_flag == 0)) //overread all except + and -
{
for (k=j; k >= 0; k--) // Search the first free place for the sign
{
if (dest[k] == ' ')
{
dest[k] = source[i];
break;
}
}
}
}
}
return 0;
}
Das ganze funktioniert ganz einfach. Man definiert einen Formatierunsstring mit den Werten "#,Z,-,+,',',.". Also auch der Dezimalpunkt/Komma, das Vorzeichen und das Tausenderkennzeichen werden berücksichtigt.
Hier ein Beispiielaufruf:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include <ctype.h>
extern int num_to_pic (char*a,char*b,char*c,int i);
int main()
{
char ergebnis[15]; //Source
char ergebnisdb[15]; // Destination
char ergebnispic[15]="####.###.###,##"; // Picture
int i=15, // length of decleration
ret;
//
signed long int zahl;
char testdisplay[21];
//
zahl = -1234567890;
sprintf (ergebnis,"%+li",zahl); // ergibt source[15]="-1234567890 "
printf("%s\n",ergebnis); // Test purpose
//
ret = num_to_pic (ergebnisdb, ergebnis, ergebnispic, i);
if (ret != 0)
printf("Invalid Picturestring\nCode: %i\n",ret);
//
strncpy(testdisplay,ergebnisdb,(size_t) i); // Result " -12.345.678,90"
testdisplay[i] = 0; // "\0"
//
printf("%s\n",testdisplay); // Test purpose
return 0;
}
Aus dem Formatierungsstring "####.###.###,##" und dem Wert "-1234567890" wird "-12.345.678,90".
Mit dem "Z" Wert kann man "0" erzwingen z.B. "0,01". Also: aus "1" wird mit dem Formatierungsstring "#.##Z,ZZ" "0,01".
Auch kann man bei negativen Werten das Vorzeichen unterdrücken (etwa für ein Bilanzkonto), indem man ein "d" oder "c" rechts an den Formatierungsstring anfügt. Aus "-1" und dem Formatierungsstring "Z,ZZd" wird dann ebenfalls "0,01"
ohne "d" wäre es "-0,01".
Ich hoffe, dass die Profis hier nicht mühsam lächeln, es war eine meiner ersten Funktionen in C...
Ach ja ... auf das Längenfeld könnte man verzichten - ich weiss (es soll aber auch Strings ohne "\0" unterstützen). Und wie man eine externe Funktion einbindet, sollte eigentlich jeder hier wissen.