6

桁区切り記号 (コンマまたはスペース) を使用して大きな数値を出力したい - 基本的には、3 桁のグループで数値を表示する方法と同じですが、C で使用printfします (GNU、99)。

printf が桁のグループ化をネイティブにサポートしていない場合、次のような方法でこれを達成するにはどうすればよいprintf("%s", group_digits(number))ですか?

負の整数とできれば浮動小数点数もサポートする必要があります。

4

7 に答える 7

12

POSIX printfを使用できる場合は、試してください

#include <locale.h>
setlocale(LC_ALL, ""); /* use user selected locale */
printf("%'d", 1000000);
于 2012-05-15T14:23:26.783 に答える
3

これを行うコンパクトな方法は次のとおりです。

// 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関数の先頭にある変数を変更することで、スペースを別の区切り文字 (コンマなど) に簡単に置き換えることができます。

于 2013-12-08T10:59:48.770 に答える
2

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
于 2015-12-11T23:02:11.257 に答える
2

負の数をサポートして、桁区切り記号をフォーマットする安全な方法:

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);
于 2015-10-28T11:42:08.497 に答える
2
#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);

}
于 2019-02-12T17:00:55.803 に答える
1
#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);
}
*/
于 2012-05-15T16:37:29.863 に答える