桁区切り記号 (コンマまたはスペース) を使用して大きな数値を出力したい - 基本的には、3 桁のグループで数値を表示する方法と同じですが、C で使用printf
します (GNU、99)。
printf が桁のグループ化をネイティブにサポートしていない場合、次のような方法でこれを達成するにはどうすればよいprintf("%s", group_digits(number))
ですか?
負の整数とできれば浮動小数点数もサポートする必要があります。
桁区切り記号 (コンマまたはスペース) を使用して大きな数値を出力したい - 基本的には、3 桁のグループで数値を表示する方法と同じですが、C で使用printf
します (GNU、99)。
printf が桁のグループ化をネイティブにサポートしていない場合、次のような方法でこれを達成するにはどうすればよいprintf("%s", group_digits(number))
ですか?
負の整数とできれば浮動小数点数もサポートする必要があります。
POSIX printfを使用できる場合は、試してください
#include <locale.h>
setlocale(LC_ALL, ""); /* use user selected locale */
printf("%'d", 1000000);
これを行うコンパクトな方法は次のとおりです。
// format 1234567.89 -> 1 234 567.89
extern char *strmoney(double value){
static char result[64];
char *result_p = result;
char separator = ' ';
size_t tail;
snprintf(result, sizeof(result), "%.2f", value);
while(*result_p != 0 && *result_p != '.')
result_p++;
tail = result + sizeof(result) - result_p;
while(result_p - result > 3){
result_p -= 3;
memmove(result_p + 1, result_p, tail);
*result_p = separator;
tail += 4;
}
return result;
}
たとえば、 を呼び出すとstrmoney(1234567891.4568)
文字列 が返されます"1 234 567 891.46"
。separator
関数の先頭にある変数を変更することで、スペースを別の区切り文字 (コンマなど) に簡単に置き換えることができます。
unsigned int64 の私自身のバージョン:
char* toString_DigitGrouping( unsigned __int64 val )
{
static char result[ 128 ];
_snprintf(result, sizeof(result), "%lld", val);
size_t i = strlen(result) - 1;
size_t i2 = i + (i / 3);
int c = 0;
result[i2 + 1] = 0;
for( ; i != 0; i-- )
{
result[i2--] = result[i];
c++;
if( c % 3 == 0 )
result[i2--] = '\'';
} //for
return result;
} //toString_DigitGrouping
負の数をサポートして、桁区切り記号をフォーマットする安全な方法:
VS < 2015 は snprintf を実装していないため、これを行う必要があります。
#if defined(_WIN32)
#define snprintf(buf,len, format,...) _snprintf_s(buf, len,len, format, __VA_ARGS__)
#endif
その後
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;
}
使用例:
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);
#include <stdio.h>
void punt(int 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(){
int a;
scanf("%d",&a);
punt(a);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *commify(char *numstr){
char *wk, *wks, *p, *ret=numstr;
int i;
wks=wk=strrev(strdup(numstr));
p = strchr(wk, '.');
if(p){//include '.'
while(wk != p)//skip until '.'
*numstr++ = *wk++;
*numstr++=*wk++;
}
for(i=1;*wk;++i){
if(isdigit(*wk)){
*numstr++=*wk++;
if(isdigit(*wk) && i % 3 == 0)
*numstr++ = ',';
} else {
break;
}
}
while(*numstr++=*wk++);
free(wks);
return strrev(ret);
}
int main(){
char buff[64];//To provide a sufficient size after conversion.
sprintf(buff, "%d", 100);
printf("%s\n", commify(buff));
sprintf(buff, "%d", 123456);
printf("%s\n", commify(buff));
sprintf(buff, "%.2f", 1234.56f);
printf("%s\n", commify(buff));
sprintf(buff, "%d", -123456);
printf("%s\n", commify(buff));
sprintf(buff, "%.2lf", -12345678.99);
printf("%s\n", commify(buff));
return 0;
}
追加:
/*
char *strrev(char *str){
char c,*front,*back;
for(front=str,back=str+strlen(str)-1;front < back;front++,back--){
c=*front;*front=*back;*back=c;
}
return(str);
}
*/