Làm thế nào tôi có thể ở định dạng ngôn ngữ C một số từ 1123456789
đến 1,123,456,789
? Tôi đã thử sử dụng printf("%'10d\n", 1123456789);
nhưng điều đó không hoạt động.
Bạn có thể tư vấn bất cứ điều gì? Giải pháp càng đơn giản càng tốt.
Làm thế nào tôi có thể ở định dạng ngôn ngữ C một số từ 1123456789
đến 1,123,456,789
? Tôi đã thử sử dụng printf("%'10d\n", 1123456789);
nhưng điều đó không hoạt động.
Bạn có thể tư vấn bất cứ điều gì? Giải pháp càng đơn giản càng tốt.
LC_NUMERIC
. Tuy nhiên, tôi không biết ngôn ngữ nào hỗ trợ điều này.
LC_NUMERIC
ngôn ngữ thành hiện tại sẽ ""
làm cho '
hoạt động trên máy Mac của tôi và trên máy linux mà tôi vừa kiểm tra.
printf()
họ hàm tiêu chuẩn hóa việc sử dụng '
ký tự (dấu nháy đơn hoặc dấu nháy đơn) với đặc điểm kỹ thuật chuyển đổi định dạng số thập phân để chỉ định rằng số phải được định dạng bằng dấu phân cách hàng nghìn.
"C"
ngôn ngữ mặc định , dấu phân tách hàng nghìn phi tiền tệ không được xác định, do đó, "%'d"
dấu phẩy sẽ không tạo ra dấu phẩy trong "C"
ngôn ngữ. Bạn cần đặt ngôn ngữ với dấu phân tách nghìn không phải tiền tệ thích hợp. Thông thường, setlocale(LC_ALL, "");
sẽ thực hiện công việc - các giá trị khác cho tên miền (ngoài chuỗi trống) được xác định thực thi.
Câu trả lời:
Nếu printf của bạn hỗ trợ '
cờ (theo yêu cầu của POSIX 2008 printf()
), bạn có thể làm điều đó chỉ bằng cách đặt ngôn ngữ của mình một cách thích hợp. Thí dụ:
#include <stdio.h>
#include <locale.h>
int main(void)
{
setlocale(LC_NUMERIC, "");
printf("%'d\n", 1123456789);
return 0;
}
Và xây dựng và chạy:
$ ./example
1,123,456,789
Đã thử nghiệm trên Mac OS X & Linux (Ubuntu 10.10).
sprintf()
trong một hệ thống nhúng và nó không hoạt động (rõ ràng, vì như bạn nói, nó sẽ không hỗ trợ 'cờ.
'
sửa đổi. Từ tiêu đề: Copyright ... 2007 Joerg Wunsch ... 1993 Regents of the University of California
tức là một dẫn xuất BSD.
Bạn có thể làm điều đó một cách đệ quy như sau (hãy cẩn thận INT_MIN
nếu bạn đang sử dụng phần bổ sung của hai, bạn sẽ cần thêm mã để quản lý điều đó):
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);
}
Một bản tóm tắt:
printfcomma
với một số nguyên, trường hợp đặc biệt của số âm được xử lý bằng cách chỉ cần in "-" và tạo số dương (đây là bit sẽ không hoạt động với INT_MIN
).printfcomma2
, một số nhỏ hơn 1.000 sẽ chỉ in và trả lại.Ngoài ra còn có phiên bản ngắn gọn hơn mặc dù nó xử lý không cần thiết trong việc kiểm tra các số âm ở mọi cấp (không phải là điều này sẽ quan trọng với số lượng giới hạn của cấp đệ quy). Đây là một chương trình hoàn chỉnh để thử nghiệm:
#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;
}
và đầu ra là:
-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
Một giải pháp lặp lại cho những người không tin tưởng đệ quy (mặc dù vấn đề duy nhất với đệ quy có xu hướng là không gian ngăn xếp sẽ không phải là vấn đề ở đây vì nó sẽ chỉ sâu một vài cấp ngay cả đối với số nguyên 64 bit):
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);
}
}
Cả hai đều tạo ra 2,147,483,647
cho INT_MAX
.
n
trong printfcomma
. Bạn cần buộc chuyển đổi thành không dấu trước khi phủ định nó.
printf
,.
Đây là một cách thực hiện rất đơn giản. Chức năng này không chứa kiểm tra lỗi, kích thước bộ đệm phải được xác nhận bởi người gọi. Nó cũng không hoạt động đối với số âm. Những cải tiến như vậy để lại như một bài tập cho người đọc.
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! Tôi làm điều này mọi lúc, sử dụng gcc / g ++ và glibc trên linux và vâng, toán tử 'có thể không chuẩn, nhưng tôi thích sự đơn giản của nó.
#include <stdio.h>
#include <locale.h>
int main()
{
int bignum=12345678;
setlocale(LC_ALL,"");
printf("Big number: %'d\n",bignum);
return 0;
}
Cung cấp đầu ra của:
Con số lớn: 12.345.678
Chỉ cần nhớ lệnh gọi 'setlocale' trong đó, nếu không nó sẽ không định dạng bất kỳ thứ gì.
'
cờ, thì bạn sẽ không nhận được đầu ra mong muốn - và điều đó độc lập với trình biên dịch. Trình biên dịch đảm bảo hàm thư viện cho printf()
được gọi với chuỗi định dạng; nó phụ thuộc vào chức năng thư viện để giải thích nó. Trên Windows, hoàn toàn có thể là thư viện CRT không cung cấp hỗ trợ bạn cần - và vấn đề không quan trọng là bạn sử dụng trình biên dịch nào.
Có lẽ một phiên bản nhận biết ngôn ngữ sẽ rất thú vị.
#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
Điều này không có một lỗi (nhưng một trong những tôi sẽ coi là khá nhỏ). Trên phần cứng bổ sung của Two, nó sẽ không chuyển đổi số âm nhất một cách chính xác, bởi vì nó cố gắng chuyển đổi một số âm thành số dương tương đương của nó với N = -N;
phần bù của Hai, số âm cực đại không có số dương tương ứng, trừ khi bạn quảng bá nó lên một loại lớn hơn. Một cách để giải quyết vấn đề này là quảng bá số thành kiểu không dấu tương ứng (nhưng nó hơi không tầm thường).
'
-flag tại đây: stackoverflow.com/q/44523855/2642059 Tôi nghĩ câu trả lời này giải quyết hoàn hảo vấn đề đó, hiện đang thực hiện thêm thử nghiệm. Nếu vậy tôi đoán tôi nên đánh dấu câu hỏi đó là một bản dupe hả?
tsep
, place_str
, và neg_str
ở tất cả? Tại sao không chỉ sử dụng trực tiếp fmt_info
các thành viên của?
while (*ptr-- = *neg_str++)
không có ý nghĩa gì đối với tôi. Bạn đang chèn các ký tự chuỗi phủ định theo thứ tự ngược lại.
Không cần đệ quy hoặc xử lý chuỗi, một cách tiếp cận toán học:
#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) ) ;
}
}
Về nguyên tắc tương tự như giải pháp đệ quy của Pax, nhưng bằng cách tính toán thứ tự độ lớn trước, đệ quy sẽ tránh được (có lẽ với một số chi phí đáng kể).
Cũng lưu ý rằng ký tự thực tế được sử dụng để phân tách hàng nghìn là đặc trưng theo ngôn ngữ.
Chỉnh sửa : Xem nhận xét của @ Chux bên dưới để cải thiện.
abs(n)
để fabs(n)
tránh lỗi khen của 2 khi biểu diễn print_number(INT_MIN)
.
log10(abs(n))
chứ không phải nơi nào khác. Thật thú vị, giải pháp của bạn hoạt động với một thay đổi duy nhất đối với log10(fabs(n))
và print_number(INT_MIN)
vì printf(..., abs(n / order_of_magnitude))
điều đó có nghĩa n = abs(INT_MIN) % order_of_magnitude
là tiêu cực là OK. Nếu chúng tôi từ bỏ INT_MIN, printf(..., abs(n / order_of_magnitude))
có thể trở thành printf(..., n / order_of_magnitude)
. Nhưng tôi cho rằng làm việc với con sâu có tên "abs (INT_MIN)" đó thường là một điều tồi tệ .
log10(fabs(n))
, n = abs(n% order_of_magnitude)
và printf(",%03d", n/order_of_magnitude)
. BTW: Tôi sẽ không tốn công sức này trừ khi tôi nghĩ rằng giải pháp của bạn là tốt. Không có UB, ngay cả đối với INT_MIN.
Dựa trên @Greg Hewgill's, nhưng tính đến số âm và trả về kích thước chuỗi.
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);
}
Câu trả lời của tôi không định dạng kết quả chính xác như hình minh họa trong câu hỏi, nhưng có thể đáp ứng nhu cầu thực tế trong một số trường hợp với một chữ lót hoặc macro đơn giản. Người ta có thể mở rộng nó để tạo thêm nghìn nhóm nếu cần.
Kết quả sẽ như sau:
Value: 0'000'012'345
Mật mã:
printf("Value: %llu'%03lu'%03lu'%03lu\n", (value / 1000 / 1000 / 1000), (value / 1000 / 1000) % 1000, (value / 1000) % 1000, value % 1000);
'
một ký hiệu tương đương tiêu chuẩn để một ,
(về mặt toán học, ít nhất) trong một số phần (s) của thế giới?
Không có cách thực sự đơn giản nào để làm điều này trong C. Tôi chỉ cần sửa đổi một hàm int-to-string để làm điều đó:
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);
}
Một hàm lặp khác
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);
}
}
Đây là cách triển khai hiệu quả về kích thước và tốc độ nhỏ nhất của loại định dạng chữ số thập phân này:
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;
}
Sử dụng như sau:
char buffer[16];
fprintf (stderr, "test : %s.", formatNumber (1234567890, buffer + 16, true));
Đầu ra:
test : +1,234,567,890.
Một số ưu điểm:
Hàm chiếm cuối bộ đệm chuỗi vì định dạng có thứ tự ngược lại. Cuối cùng, không cần cung cấp lại chuỗi được tạo (strrev).
Hàm này tạo ra một chuỗi có thể được sử dụng trong bất kỳ bí danh nào sau đó. Nó không phụ thuộc cũng như không yêu cầu nhiều cuộc gọi printf / sprintf, điều này rất chậm và luôn theo ngữ cảnh cụ thể.
unlikely
gì?
unlikely
có thể là một gợi ý cho trình tối ưu hóa rằng điều kiện không chắc là đúng. Xem likely()
/ unlikely()
macro trong nhân Linux để biết thêm thông tin.
An toàn format_commas, với số âm:
Vì VS <2015 không triển khai snprintf nên bạn cần thực hiện việc này
#if defined(_WIN32)
#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
#endif
Và sau đó
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;
}
Ví dụ sử dụng:
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);
Một phiên bản sửa đổi của giải pháp @paxdiablo, nhưng sử dụng WCHAR
và 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);
}
Tôi mới học lập trình C. Đây là mã đơn giản của tôi.
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 ...
}
Giải pháp của tôi sử dụng a. thay vì a, Người đọc phải thay đổi điều này.
Câu này đã cũ và có rất nhiều câu trả lời nhưng câu hỏi không phải là "làm thế nào tôi có thể viết một thói quen để thêm dấu phẩy" mà là "làm thế nào nó có thể được thực hiện trong C"? Các nhận xét chỉ ra hướng này nhưng trên hệ thống Linux của tôi với GCC, điều này phù hợp với tôi:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main()
{
unsetenv("LC_ALL");
setlocale(LC_NUMERIC, "");
printf("%'lld\n", 3141592653589);
}
Khi điều này được chạy, tôi nhận được:
$ cc -g comma.c -o comma && ./comma
3,141,592,653,589
Nếu tôi bỏ đặt LC_ALL
biến trước khi chạy chương trình unsetenv
thì không cần thiết.
Cần thiết để tự mình làm điều gì đó tương tự nhưng thay vì in trực tiếp, cần phải chuyển đến bộ đệm. Đây là những gì tôi nghĩ ra. Hoạt động ngược.
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;
}
Lưu ý rằng nó chỉ được thiết kế cho các số nguyên không dấu và bạn phải đảm bảo rằng bộ đệm đủ lớn.
Một giải pháp khác, bằng cách lưu kết quả vào một int
mảng, kích thước tối đa là 7 vì long long int
kiểu có thể xử lý các số trong phạm vi 9.223.372.036.854.775.807 đến -9.223.372.036.854.775.807 . (Lưu ý nó không phải là giá trị không dấu).
Chức năng in không đệ quy
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]);
}
}
}
}
cuộc gọi chức năng chính
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
}
kiểm tra đầu ra
-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
Trong hàm main ():
int numberSeparated[8];
long long int number = 1234567890LL;
getNumWcommas(number, numberSeparated);
Nếu in là tất cả những gì cần thiết thì hãy chuyển int numberSeparated[8];
vào bên trong hàm getNumWcommas
và gọi nó theo cách này getNumWcommas(number)
.
Có thể được thực hiện khá dễ dàng ...
//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';
}
Cuộc gọi ví dụ:
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(",");
}
}
,
cho các số bên dưới 100
, sử dụng printf()
nơi putchar()
sẽ bay, sử dụng tên gây hiểu lầm, thụt lề lộn xộn và quá nhiều mã.
// 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
có thể biến mất. Mã không tạo ra bất kỳ thứ gì cho 0. Nó không xử lý các số âm. Không có lý do rõ ràng để tạo buffer
một static
biến (nó hạn chế sự xuất hiện gần đây của mã). Không có giải thích về những gì nó làm, hoặc đề cập rằng sau khi mã hoàn tất, chuỗi được trỏ đến p
chứa chuỗi được định dạng. Vấn đề ít nghiêm trọng nhất là nó sử dụng khoảng trống thay vì dấu phẩy làm dấu phân cách hàng nghìn. Tuy nhiên, thực tế là nó không xử lý số 0 là vấn đề giết người.
printf()
hàm IO được định dạng (ký tự dấu nháy đơn: ') là cờ không chuẩn chỉ được hỗ trợ trong một số triển khai thư viện. Thật tệ là nó không chuẩn.