Jak mogę w języku C formatować liczbę od 1123456789
do 1,123,456,789
? Próbowałem użyć, printf("%'10d\n", 1123456789);
ale to nie działa.
Czy mógłbyś coś doradzić? Im prostsze rozwiązanie, tym lepiej.
Jak mogę w języku C formatować liczbę od 1123456789
do 1,123,456,789
? Próbowałem użyć, printf("%'10d\n", 1123456789);
ale to nie działa.
Czy mógłbyś coś doradzić? Im prostsze rozwiązanie, tym lepiej.
LC_NUMERIC
. Jednak nie wiem, które locale to obsługuje.
LC_NUMERIC
locale na aktualne ""
sprawia, że '
działa na moim Macu i na komputerze z Linuksem, który właśnie sprawdziłem.
printf()
rodziny funkcji POSIX 2008 (2013) standaryzują użycie '
znaku (pojedynczego cudzysłowu lub apostrofu) ze specyfikacjami konwersji formatowania liczb dziesiętnych, aby określić, że liczba powinna być sformatowana z separatorami tysięcy.
"C"
ustawieniu narodowym niepieniężny separator tysięcy jest niezdefiniowany, więc "%'d"
w "C"
ustawieniach regionalnych nie zostaną utworzone przecinki . Musisz ustawić ustawienia regionalne z odpowiednim niepieniężnym separatorem tysięcy. Często setlocale(LC_ALL, "");
wykona zadanie - inne wartości dla nazwy locale (inne niż pusty łańcuch) są zdefiniowane jako implementacja.
Odpowiedzi:
Jeśli twój printf obsługuje '
flagę (zgodnie z wymaganiami POSIX 2008 printf()
), prawdopodobnie możesz to zrobić po prostu ustawiając odpowiednio swoje locale. Przykład:
#include <stdio.h>
#include <locale.h>
int main(void)
{
setlocale(LC_NUMERIC, "");
printf("%'d\n", 1123456789);
return 0;
}
I buduj i uruchamiaj:
$ ./example
1,123,456,789
Przetestowano na Mac OS X i Linux (Ubuntu 10.10).
sprintf()
w systemie wbudowanym i nie działa (oczywiście, ponieważ jak mówisz, nie obsługuje flagi „.
'
modyfikatora. Z nagłówka: Copyright ... 2007 Joerg Wunsch ... 1993 Regents of the University of California
tj. Pochodna BSD.
Możesz to zrobić rekurencyjnie w następujący sposób (uważaj, INT_MIN
jeśli używasz dopełnienia do dwóch, będziesz potrzebować dodatkowego kodu do zarządzania tym):
void printfcomma2 (int n) {
if (n < 1000) {
printf ("%d", n);
return;
}
printfcomma2 (n/1000);
printf (",%03d", n%1000);
}
void printfcomma (int n) {
if (n < 0) {
printf ("-");
n = -n;
}
printfcomma2 (n);
}
Podsumowanie:
printfcomma
liczbę całkowitą, specjalny przypadek liczb ujemnych jest obsługiwany przez proste wypisanie "-" i uczynienie liczby dodatnią (jest to bit, który nie zadziałaINT_MIN
).printfcomma2
liczba mniejsza niż 1000 zostanie po prostu wydrukowana i zwrócona.Istnieje również bardziej zwięzła wersja, chociaż wykonuje niepotrzebne przetwarzanie podczas sprawdzania liczb ujemnych na każdym poziomie (nie ma to znaczenia, biorąc pod uwagę ograniczoną liczbę poziomów rekursji). Ten jest kompletnym programem do testowania:
#include <stdio.h>
void printfcomma (int n) {
if (n < 0) {
printf ("-");
printfcomma (-n);
return;
}
if (n < 1000) {
printf ("%d", n);
return;
}
printfcomma (n/1000);
printf (",%03d", n%1000);
}
int main (void) {
int x[] = {-1234567890, -123456, -12345, -1000, -999, -1,
0, 1, 999, 1000, 12345, 123456, 1234567890};
int *px = x;
while (px != &(x[sizeof(x)/sizeof(*x)])) {
printf ("%-15d: ", *px);
printfcomma (*px);
printf ("\n");
px++;
}
return 0;
}
a wynik to:
-1234567890 : -1,234,567,890
-123456 : -123,456
-12345 : -12,345
-1000 : -1,000
-999 : -999
-1 : -1
0 : 0
1 : 1
999 : 999
1000 : 1,000
12345 : 12,345
123456 : 123,456
1234567890 : 1,234,567,890
Iteracyjne rozwiązanie dla tych, którzy nie ufają rekursji (chociaż jedynym problemem związanym z rekurencją jest zwykle miejsce na stosie, które nie będzie tutaj problemem, ponieważ będzie to tylko kilka poziomów głębokości, nawet dla 64-bitowej liczby całkowitej):
void printfcomma (int n) {
int n2 = 0;
int scale = 1;
if (n < 0) {
printf ("-");
n = -n;
}
while (n >= 1000) {
n2 = n2 + scale * (n % 1000);
n /= 1000;
scale *= 1000;
}
printf ("%d", n);
while (scale != 1) {
scale /= 1000;
n = n2 / scale;
n2 = n2 % scale;
printf (",%03d", n);
}
}
Oba generują 2,147,483,647
dla INT_MAX
.
Cały powyższy kod dotyczy grup trzycyfrowych oddzielonych przecinkami, ale możesz też użyć innych znaków, takich jak spacja:
void printfspace2 (int n) {
if (n < 1000) {
printf ("%d", n);
return;
}
printfspace2 (n/1000);
printf (" %03d", n%1000);
}
void printfspace (int n) {
if (n < 0) {
printf ("-");
n = -n;
}
printfspace2 (n);
}
n
w printfcomma
. Musisz wymusić konwersję na unsigned przed jej zanegowaniem.
printf
.
Oto bardzo prosta implementacja. Ta funkcja nie zawiera sprawdzania błędów, rozmiar bufora musi zostać zweryfikowany przez wywołującego. Nie działa również dla liczb ujemnych. Takie ulepszenia pozostawia się czytelnikowi jako ćwiczenie.
void format_commas(int n, char *out)
{
int c;
char buf[20];
char *p;
sprintf(buf, "%d", n);
c = 2 - strlen(buf) % 3;
for (p = buf; *p != 0; p++) {
*out++ = *p;
if (c == 1) {
*out++ = ',';
}
c = (c + 1) % 3;
}
*--out = 0;
}
Egads! Robię to cały czas, używając gcc / g ++ i glibc na Linuksie i tak, operator 'może być niestandardowy, ale podoba mi się jego prostota.
#include <stdio.h>
#include <locale.h>
int main()
{
int bignum=12345678;
setlocale(LC_ALL,"");
printf("Big number: %'d\n",bignum);
return 0;
}
Daje wynik:
Duża liczba: 12,345,678
Wystarczy zapamiętać wywołanie „setlocale”, w przeciwnym razie nic nie sformatuje.
'
flagi, to nie otrzymasz żądanego wyniku - i jest to niezależne od kompilatora. Kompilator zapewnia, że funkcja biblioteki dla printf()
jest wywoływana za pomocą ciągu formatu; interpretacja tego zależy od funkcji biblioteki. W systemie Windows jest całkowicie możliwe, że biblioteka CRT nie zapewnia potrzebnego wsparcia - i nie ma znaczenia, którego kompilatora używasz.
Być może wersja uwzględniająca locale byłaby interesująca.
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <limits.h>
static int next_group(char const **grouping) {
if ((*grouping)[1] == CHAR_MAX)
return 0;
if ((*grouping)[1] != '\0')
++*grouping;
return **grouping;
}
size_t commafmt(char *buf, /* Buffer for formatted string */
int bufsize, /* Size of buffer */
long N) /* Number to convert */
{
int i;
int len = 1;
int posn = 1;
int sign = 1;
char *ptr = buf + bufsize - 1;
struct lconv *fmt_info = localeconv();
char const *tsep = fmt_info->thousands_sep;
char const *group = fmt_info->grouping;
char const *neg = fmt_info->negative_sign;
size_t sep_len = strlen(tsep);
size_t group_len = strlen(group);
size_t neg_len = strlen(neg);
int places = (int)*group;
if (bufsize < 2)
{
ABORT:
*buf = '\0';
return 0;
}
*ptr-- = '\0';
--bufsize;
if (N < 0L)
{
sign = -1;
N = -N;
}
for ( ; len <= bufsize; ++len, ++posn)
{
*ptr-- = (char)((N % 10L) + '0');
if (0L == (N /= 10L))
break;
if (places && (0 == (posn % places)))
{
places = next_group(&group);
for (int i=sep_len; i>0; i--) {
*ptr-- = tsep[i-1];
if (++len >= bufsize)
goto ABORT;
}
}
if (len >= bufsize)
goto ABORT;
}
if (sign < 0)
{
if (len >= bufsize)
goto ABORT;
for (int i=neg_len; i>0; i--) {
*ptr-- = neg[i-1];
if (++len >= bufsize)
goto ABORT;
}
}
memmove(buf, ++ptr, len + 1);
return (size_t)len;
}
#ifdef TEST
#include <stdio.h>
#define elements(x) (sizeof(x)/sizeof(x[0]))
void show(long i) {
char buffer[32];
commafmt(buffer, sizeof(buffer), i);
printf("%s\n", buffer);
commafmt(buffer, sizeof(buffer), -i);
printf("%s\n", buffer);
}
int main() {
long inputs[] = {1, 12, 123, 1234, 12345, 123456, 1234567, 12345678 };
for (int i=0; i<elements(inputs); i++) {
setlocale(LC_ALL, "");
show(inputs[i]);
}
return 0;
}
#endif
Ma to błąd (ale uważam go za dość niewielki). Na sprzęcie z dopełnieniem do dwóch nie przekształci poprawnie liczby najbardziej ujemnej, ponieważ próbuje zamienić liczbę ujemną na jej równoważną liczbę dodatnią z N = -N;
uzupełnieniem do dwóch, maksymalna liczba ujemna nie ma odpowiadającej liczby dodatniej, chyba że promować go do większego typu. Jednym ze sposobów obejścia tego jest promowanie liczby odpowiadającej typowi bez znaku (ale jest to nieco nietrywialne).
'
-flag tutaj: stackoverflow.com/q/44523855/2642059 Myślę, że ta odpowiedź doskonale to rozwiązuje, wykonując teraz więcej testów. Jeśli tak, to chyba powinienem oznaczyć to pytanie jako dupe, co?
tsep
, place_str
i neg_str
w ogóle? Dlaczego po prostu nie użyć bezpośrednio fmt_info
członków?
while (*ptr-- = *neg_str++)
nie ma to dla mnie sensu. Wstawiasz ujemne znaki łańcuchowe w odwrotnej kolejności.
Matematyczne podejście bez rekurencji lub obsługi ciągów:
#include <stdio.h>
#include <math.h>
void print_number( int n )
{
int order_of_magnitude = (n == 0) ? 1 : (int)pow( 10, ((int)floor(log10(abs(n))) / 3) * 3 ) ;
printf( "%d", n / order_of_magnitude ) ;
for( n = abs( n ) % order_of_magnitude, order_of_magnitude /= 1000;
order_of_magnitude > 0;
n %= order_of_magnitude, order_of_magnitude /= 1000 )
{
printf( ",%03d", abs(n / order_of_magnitude) ) ;
}
}
Podobnie jak w przypadku rozwiązania rekurencyjnego Paxa, ale obliczając rząd wielkości z wyprzedzeniem, unika się rekursji (być może przy znacznych kosztach).
Zauważ również, że rzeczywisty znak używany do oddzielania tysięcy jest specyficzny dla lokalizacji.
Edycja : zobacz komentarze @ Chux poniżej, aby uzyskać ulepszenia.
abs(n)
na fabs(n)
zapobiega błędom komplementu 2 podczas wykonywania print_number(INT_MIN)
.
log10(abs(n))
a nie gdzie indziej. Co ciekawe, twoje rozwiązanie działa z pojedynczą zmianą do log10(fabs(n))
iz print_number(INT_MIN)
powodu, printf(..., abs(n / order_of_magnitude))
co oznacza, n = abs(INT_MIN) % order_of_magnitude
że bycie negatywnym jest w porządku. Jeśli zrezygnujemy z INT_MIN, printf(..., abs(n / order_of_magnitude))
może się stać printf(..., n / order_of_magnitude)
. Ale przypuszczam, że praca z robakiem o nazwie „abs (INT_MIN)” jest zwykle zła .
log10(fabs(n))
, n = abs(n% order_of_magnitude)
i printf(",%03d", n/order_of_magnitude)
. Przy okazji: nie wydałbym tego wysiłku, chyba że uważam, że twoje rozwiązanie jest dobre. Brak UB, nawet dla INT_MIN.
Oparty na @Greg Hewgill's, ale bierze pod uwagę liczby ujemne i zwraca rozmiar ciągu.
size_t str_format_int_grouped(char dst[16], int num)
{
char src[16];
char *p_src = src;
char *p_dst = dst;
const char separator = ',';
int num_len, commas;
num_len = sprintf(src, "%d", num);
if (*p_src == '-') {
*p_dst++ = *p_src++;
num_len--;
}
for (commas = 2 - num_len % 3;
*p_src;
commas = (commas + 1) % 3)
{
*p_dst++ = *p_src++;
if (commas == 1) {
*p_dst++ = separator;
}
}
*--p_dst = '\0';
return (size_t)(p_dst - dst);
}
Moja odpowiedź nie formatuje wyniku dokładnie tak, jak na ilustracji w pytaniu, ale może w niektórych przypadkach zaspokoić rzeczywistą potrzebę za pomocą prostego jednowierszowego lub makra. W razie potrzeby można go rozszerzyć, aby wygenerować więcej tysięcy grup.
Wynik będzie wyglądał na przykład następująco:
Value: 0'000'012'345
Kod:
printf("Value: %llu'%03lu'%03lu'%03lu\n", (value / 1000 / 1000 / 1000), (value / 1000 / 1000) % 1000, (value / 1000) % 1000, value % 1000);
'
standardowa notacja jest równoważna ,
(przynajmniej matematycznie) w jakiejś części świata?
Nie ma naprawdę prostego sposobu na zrobienie tego w C. Po prostu zmodyfikowałbym funkcję int-to-string, aby to zrobić:
void format_number(int n, char * out) {
int i;
int digit;
int out_index = 0;
for (i = n; i != 0; i /= 10) {
digit = i % 10;
if ((out_index + 1) % 4 == 0) {
out[out_index++] = ',';
}
out[out_index++] = digit + '0';
}
out[out_index] = '\0';
// then you reverse the out string as it was converted backwards (it's easier that way).
// I'll let you figure that one out.
strrev(out);
}
Kolejna funkcja iteracyjna
int p(int n) {
if(n < 0) {
printf("-");
n = -n;
}
int a[sizeof(int) * CHAR_BIT / 3] = { 0 };
int *pa = a;
while(n > 0) {
*++pa = n % 1000;
n /= 1000;
}
printf("%d", *pa);
while(pa > a + 1) {
printf(",%03d", *--pa);
}
}
Oto najcieńsza, wydajna pod względem wielkości i szybkości implementacja tego rodzaju formatowania cyfr dziesiętnych:
const char *formatNumber (
int value,
char *endOfbuffer,
bool plus)
{
int savedValue;
int charCount;
savedValue = value;
if (unlikely (value < 0))
value = - value;
*--endOfbuffer = 0;
charCount = -1;
do
{
if (unlikely (++charCount == 3))
{
charCount = 0;
*--endOfbuffer = ',';
}
*--endOfbuffer = (char) (value % 10 + '0');
}
while ((value /= 10) != 0);
if (unlikely (savedValue < 0))
*--endOfbuffer = '-';
else if (unlikely (plus))
*--endOfbuffer = '+';
return endOfbuffer;
}
Użyj w następujący sposób:
char buffer[16];
fprintf (stderr, "test : %s.", formatNumber (1234567890, buffer + 16, true));
Wynik:
test : +1,234,567,890.
Niektóre zalety:
Funkcja pobierająca koniec bufora ciągu z powodu odwrotnego uporządkowania formatowania. Wreszcie, gdzie nie ma potrzeby cofania wygenerowanego ciągu (strrev).
Ta funkcja tworzy jeden ciąg, którego można użyć w dowolnym algo po. Nie zależy ani nie wymaga wielu wywołań printf / sprintf, co jest strasznie powolne i zawsze zależy od kontekstu.
unlikely
?
unlikely
prawdopodobnie jest wskazówką dla optymalizatora, że warunek prawdopodobnie nie jest prawdziwy. Aby uzyskać więcej informacji, zobacz likely()
/ unlikely()
macros w jądrze Linuksa .
Bezpieczny format_commas, z liczbami ujemnymi:
Ponieważ VS <2015 nie implementuje snprintf, musisz to zrobić
#if defined(_WIN32)
#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
#endif
I wtedy
char* format_commas(int n, char *out)
{
int c;
char buf[100];
char *p;
char* q = out; // Backup pointer for return...
if (n < 0)
{
*out++ = '-';
n = abs(n);
}
snprintf(buf, 100, "%d", n);
c = 2 - strlen(buf) % 3;
for (p = buf; *p != 0; p++) {
*out++ = *p;
if (c == 1) {
*out++ = '\'';
}
c = (c + 1) % 3;
}
*--out = 0;
return q;
}
Przykładowe użycie:
size_t currentSize = getCurrentRSS();
size_t peakSize = getPeakRSS();
printf("Current size: %d\n", currentSize);
printf("Peak size: %d\n\n\n", peakSize);
char* szcurrentSize = (char*)malloc(100 * sizeof(char));
char* szpeakSize = (char*)malloc(100 * sizeof(char));
printf("Current size (f): %s\n", format_commas((int)currentSize, szcurrentSize));
printf("Peak size (f): %s\n", format_commas((int)currentSize, szpeakSize));
free(szcurrentSize);
free(szpeakSize);
Zmodyfikowana wersja rozwiązania @paxdiablo, ale używająca WCHAR
i wsprinf
:
static WCHAR buffer[10];
static int pos = 0;
void printfcomma(const int &n) {
if (n < 0) {
wsprintf(buffer + pos, TEXT("-"));
pos = lstrlen(buffer);
printfcomma(-n);
return;
}
if (n < 1000) {
wsprintf(buffer + pos, TEXT("%d"), n);
pos = lstrlen(buffer);
return;
}
printfcomma(n / 1000);
wsprintf(buffer + pos, TEXT(",%03d"), n % 1000);
pos = lstrlen(buffer);
}
void my_sprintf(const int &n)
{
pos = 0;
printfcomma(n);
}
Jestem nowy w programowaniu w C. Oto mój prosty kod.
int main()
{
// 1223 => 1,223
int n;
int a[10];
printf(" n: ");
scanf_s("%d", &n);
int i = 0;
while (n > 0)
{
int temp = n % 1000;
a[i] = temp;
n /= 1000;
i++;
}
for (int j = i - 1; j >= 0; j--)
{
if (j == 0)
{
printf("%d.", a[j]);
}
else printf("%d,",a[j]);
}
getch();
return 0;
}
#include <stdio.h>
void punt(long long n){
char s[28];
int i = 27;
if(n<0){n=-n; putchar('-');}
do{
s[i--] = n%10 + '0';
if(!(i%4) && n>9)s[i--]='.';
n /= 10;
}while(n);
puts(&s[++i]);
}
int main(){
punt(2134567890);
punt(987);
punt(9876);
punt(-987);
punt(-9876);
punt(-654321);
punt(0);
punt(1000000000);
punt(0x7FFFFFFFFFFFFFFF);
punt(0x8000000000000001); // -max + 1 ...
}
Moje rozwiązanie wykorzystuje plik. zamiast a, Czytelnik może to zmienić.
To jest stare i istnieje wiele odpowiedzi, ale pytanie nie brzmiało „jak napisać procedurę dodawania przecinków”, ale „jak to zrobić w C”? Komentarze wskazywały na ten kierunek, ale w moim systemie Linux z GCC działa to dla mnie:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
unsetenv("LC_ALL");
setlocale(LC_NUMERIC, "");
printf("%'lld\n", 3141592653589);
}
Po uruchomieniu otrzymuję:
$ cc -g comma.c -o comma && ./comma
3,141,592,653,589
Jeśli wyłączę LC_ALL
zmienną przed uruchomieniem programu, unsetenv
nie jest to konieczne.
Musiałem zrobić coś podobnego sam, ale zamiast drukować bezpośrednio, musiałem przejść do bufora. Oto, co wymyśliłem. Działa wstecz.
unsigned int IntegerToCommaString(char *String, unsigned long long Integer)
{
unsigned int Digits = 0, Offset, Loop;
unsigned long long Copy = Integer;
do {
Digits++;
Copy /= 10;
} while (Copy);
Digits = Offset = ((Digits - 1) / 3) + Digits;
String[Offset--] = '\0';
Copy = Integer;
Loop = 0;
do {
String[Offset] = '0' + (Copy % 10);
if (!Offset--)
break;
if (Loop++ % 3 == 2)
String[Offset--] = ',';
Copy /= 10;
} while (1);
return Digits;
}
Należy pamiętać, że jest przeznaczony tylko dla liczb całkowitych bez znaku i należy upewnić się, że bufor jest wystarczająco duży.
Innym rozwiązaniem jest zapisanie wyniku w int
tablicy o maksymalnym rozmiarze 7, ponieważ long long int
typ może obsługiwać liczby z zakresu od 9 223 372 036 854 775 807 do -9 223 372 036 854 775 807 . (Zauważ, że nie jest to wartość bez znaku).
Nierekurencyjna funkcja drukowania
static void printNumber (int numbers[8], int loc, int negative)
{
if (negative)
{
printf("-");
}
if (numbers[1]==-1)//one number
{
printf("%d ", numbers[0]);
}
else
{
printf("%d,", numbers[loc]);
while(loc--)
{
if(loc==0)
{// last number
printf("%03d ", numbers[loc]);
break;
}
else
{ // number in between
printf("%03d,", numbers[loc]);
}
}
}
}
główne wywołanie funkcji
static void getNumWcommas (long long int n, int numbers[8])
{
int i;
int negative=0;
if (n < 0)
{
negative = 1;
n = -n;
}
for(i = 0; i < 7; i++)
{
if (n < 1000)
{
numbers[i] = n;
numbers[i+1] = -1;
break;
}
numbers[i] = n%1000;
n/=1000;
}
printNumber(numbers, i, negative);// non recursive print
}
testowanie wyjścia
-9223372036854775807: -9,223,372,036,854,775,807
-1234567890 : -1,234,567,890
-123456 : -123,456
-12345 : -12,345
-1000 : -1,000
-999 : -999
-1 : -1
0 : 0
1 : 1
999 : 999
1000 : 1,000
12345 : 12,345
123456 : 123,456
1234567890 : 1,234,567,890
9223372036854775807 : 9,223,372,036,854,775,807
W funkcji main ():
int numberSeparated[8];
long long int number = 1234567890LL;
getNumWcommas(number, numberSeparated);
Jeśli potrzebne jest tylko drukowanie, przejdź int numberSeparated[8];
do funkcji getNumWcommas
i nazwij to w ten sposób getNumWcommas(number)
.
Można to zrobić całkiem łatwo ...
//Make sure output buffer is big enough and that input is a valid null terminated string
void pretty_number(const char* input, char * output)
{
int iInputLen = strlen(input);
int iOutputBufferPos = 0;
for(int i = 0; i < iInputLen; i++)
{
if((iInputLen-i) % 3 == 0 && i != 0)
{
output[iOutputBufferPos++] = ',';
}
output[iOutputBufferPos++] = input[i];
}
output[iOutputBufferPos] = '\0';
}
Przykładowe połączenie:
char szBuffer[512];
pretty_number("1234567", szBuffer);
//strcmp(szBuffer, "1,234,567") == 0
void printfcomma ( long long unsigned int n)
{
char nstring[100];
int m;
int ptr;
int i,j;
sprintf(nstring,"%llu",n);
m=strlen(nstring);
ptr=m%3;
if (ptr)
{ for (i=0;i<ptr;i++) // print first digits before comma
printf("%c", nstring[i]);
printf(",");
}
j=0;
for (i=ptr;i<m;i++) // print the rest inserting commas
{
printf("%c",nstring[i]);
j++;
if (j%3==0)
if(i<(m-1)) printf(",");
}
}
,
liczby poniżej 100
, używa printf()
dokąd putchar()
poleciałby, używa mylących nazw, chaotycznych wcięć i zdecydowanie za dużo kodu.
// separate thousands
int digit;
int idx = 0;
static char buffer[32];
char* p = &buffer[32];
*--p = '\0';
for (int i = fCounter; i != 0; i /= 10)
{
digit = i % 10;
if ((p - buffer) % 4 == 0)
*--p = ' ';
*--p = digit + '0';
}
idx
może zostać usunięta. Kod nie daje nic dla 0. Nie obsługuje liczb ujemnych. Nie ma żadnego oczywistego powodu, aby buffer
się static
zmienną (ogranicza ponowne wejścia kodu). Nie ma wyjaśnienia, co robi, ani nie wspomina się, że po zakończeniu kodu ciąg wskazywany przez p
zawiera sformatowany ciąg. Najmniej poważny problem polega na tym, że jako separator tysięcy używa spacji zamiast przecinka. Fakt, że nie obsługuje zera, jest jednak zabójczym problemem.
printf()
rodziny sformatowanych funkcji we / wy (znak pojedynczego cudzysłowu: „) to niestandardowa flaga obsługiwana tylko w kilku implementacjach bibliotek. Szkoda, że to nie jest standard.