Zahlen unterteilungs Punkte



  • Der C Standard bietet hierfür nichts an, aber POSIX mit dem Apostroph im Formatspezifizierer:

    #ifndef _POSIX_SOURCE
    #error nix da
    #endif
    
    int main()
    {
      setlocale(LC_ALL,"");
      printf("%'d",INT_MAX);
      return 0;
    }
    

    Wenn du dort Kommas erhälst aber Punkte haben willst, wird es noch mehr plattformabhängig, du kannst verschiedene dort verfügbare locales ausprobieren, "German", "german", "deutsch", ...


  • Mod

    Wutz schrieb:

    Wenn du dort Kommas erhälst aber Punkte haben willst, wird es noch mehr plattformabhängig, du kannst verschiedene dort verfügbare locales ausprobieren, "German", "german", "deutsch", ...

    Ich denke, in dem Fall ist es eigentlich eine recht gute Idee, so wie du es vormachst, die Entscheidung darüber bei der Systemlocale "" zu lassen.



  • Danke für die Hilfe,

    hab es hinbekommen hier die fertige Funktion

    void punkte_setzen( int a )
    {
        int t   = 0;  
        int tr  = a % 1000;  
        int mr  = a % 1000000 / 1000;
        int cr  = a % 1000000000 / 1000000;
    
        if ( a >= 1000 && a <= 999999 )
        {
            t  = a / 1000;
            printf( "%d.%03d\n", t, tr );
        }    
        if ( a >= 1000000 && a <= 999999999 )
        {
            t  = a / 1000000;
            printf( "%d.%03d.%03d\n", t, mr, tr );
        }   
        if ( a >= 1000000000 && a <= 4000000000 )
        {
            t  = a / 1000000000;
            printf( "%d.%03d.%03d.%03d\n", t, cr, mr, tr );
        }
    }
    

    da ich noch Anfäner bin würde ich mich über verbesserungs Vorschläge freuen.



  • Wird bei Dir 105538007 als 105.538.7 angezeigt?



  • Vielleicht ist das eine weitere Überlegung wert. Nicht, weil es besser wäre, sondern weil es durch die Rekursion so hübsch kompliziert ist.

    #include <stdio.h>
    
    void punkte_setzen(int a)
    {
        int vorne=a/1000;//vorne nenne ich die Ziffern vor dem letzten Tausenderpunkt
        int hinten=a%1000;//und hinten nenne ich die letzten drei Ziffern
        if(vorne==0)//wenn vorne nichts ist, dann
        {
            printf("%d",hinten);//normal ausgeben
        }
        else//aber wenn vorne doch etwas ist, dann
        {
            punkte_setzen(vorne);//erst vorne ausgeben, und zwar ganz normal, mit ebendieser Funktion punkte_setzen()
            printf(".%03d",a%1000);//und dann den punkt und mit durch 0 auf drei Stellen aufgefüllt hinten
        }
    }
    
    int main()
    {
        punkte_setzen(15538007);
        return 0;
    }
    


  • Hab den Fehler mit den 0 Stellen behoben. Danke war mir garnicht aufgefallen.



  • void punkte_setzen(int a)
    {
        int vorne=a/1000;//vorne nenne ich die Ziffern vor dem letzten Tausenderpunkt
        int hinten=a%1000;//und hinten nenne ich die letzten drei Ziffern
        if(vorne==0)//wenn vorne nichts ist, dann
        {
            printf("%d",hinten);//normal ausgeben
        }
        else//aber wenn vorne doch etwas ist, dann
        {
            punkte_setzen(vorne);//erst vorne ausgeben, und zwar ganz normal, mit ebendieser Funktion punkte_setzen()
            printf(".%03d",a%1000);//und dann den punkt und mit durch 0 auf drei Stellen aufgefüllt hinten
        }
    }
    

    Warum hinten=a%1000, wenn vorne 0 wäre?
    Warum im else bei printf a%1000, wenn du doch schon in "hinten" ausgerechnet hast?

    void punkte_setzen(int a)
    {
        int vorne=a/1000;//vorne nenne ich die Ziffern vor dem letzten Tausenderpunkt
        int hinten;//und hinten nenne ich die letzten drei Ziffern
        if(vorne==0)//wenn vorne nichts ist, dann
        {
            printf("%d",a);//normal ausgeben
        }
        else//aber wenn vorne doch etwas ist, dann
        {
            hinten=a%1000;
            punkte_setzen(vorne);//erst vorne ausgeben, und zwar ganz normal, mit ebendieser Funktion punkte_setzen()
            printf(".%03d",hinten);//und dann den punkt und mit durch 0 auf drei Stellen aufgefüllt hinten
        }
    }
    

    Oder lass ich mich gerade durch die Rekursion verwirren?



  • DaRe schrieb:

    Warum im else bei printf a%1000, wenn du doch schon in "hinten" ausgerechnet hast?

    Schussligkeit. Natürlich will ich hinten auch benutzen, wenn ich es schon ausgerechnet habe.



  • DaRe schrieb:

    Warum hinten=a%1000, wenn vorne 0 wäre?

    Die beiden Variablen hatte ich nur ausgelagert, um bessere Kommentare schreiben zu können.

    Vielleicht sollte man auf a<1000 testen.



  • 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.


Anmelden zum Antworten