以下代码将字节数转换成字符串形式的尺寸描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SECTOR_SIZE_DEFAULT   512LL
#define KILOBYTE_SIZE 1000LL
#define MEGABYTE_SIZE 1000000LL
#define GIGABYTE_SIZE 1000000000LL
#define TERABYTE_SIZE 1000000000000LL
#define KIBIBYTE_SIZE 1024LL
#define MEBIBYTE_SIZE 1048576LL
#define GIBIBYTE_SIZE 1073741824LL
#define TEBIBYTE_SIZE 1099511627776LL

typedef enum
{
    BASE_BINARY,
    BASE_DECIMAL
} Base;

typedef enum {
    DIGIT_UNIT_BYTE,
    DIGIT_UNIT_KILOBYTE,
    DIGIT_UNIT_MEGABYTE,
    DIGIT_UNIT_GIGABYTE,
    DIGIT_UNIT_TERABYTE,
    DIGIT_UNIT_KIBIBYTE,
    DIGIT_UNIT_MEBIBYTE,
    DIGIT_UNIT_GIBIBYTE,
    DIGIT_UNIT_TEBIBYTE
} DigitUnit;

char *
unit_format_custom (long long n, DigitUnit unit)
{
    char *str = malloc(64);
    memset (str, 0, 64);
    float f;
    int len;
    char *suffix;
    
    switch (unit)
    {
    case DIGIT_UNIT_BYTE:
    {
        sprintf (str, "%lld%s", n, "B");
        break;
    }
    case DIGIT_UNIT_KILOBYTE:
    {
        f = (float) n / KILOBYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "K");
        break;
    }
    case DIGIT_UNIT_MEGABYTE:
    {
        f = (float) n / MEGABYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "M");
        break;
    }
    case DIGIT_UNIT_GIGABYTE:
    {
        f = (float) n / GIGABYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "G");
        break;
    }
    case DIGIT_UNIT_TERABYTE:
    {
        f = (float) n / TERABYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "T");
        break;
    }
    case DIGIT_UNIT_KIBIBYTE:
    {
        f = (float) n / KIBIBYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "Ki");
        break;
    }
    case DIGIT_UNIT_MEBIBYTE:
    {
        f = (float) n / MEBIBYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "Mi");
        break;
    }
    case DIGIT_UNIT_GIBIBYTE:
    {
        f = (float) n / GIBIBYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "Gi");
        break;
    }
    case DIGIT_UNIT_TEBIBYTE:
    {
        f = (float) n / TEBIBYTE_SIZE;
        sprintf (str, "%.1f", f);
        len = strlen(str);
        suffix = (*(str + (len - 1)) == '0') ? str + len - 2 : str + len;
        memset (suffix, 0, 2);
        sprintf (suffix, "%s", "Ti");
        break;
    }
    }

    return str;
}

char *
unit_format (long long n, Base base)
{
    DigitUnit unit = DIGIT_UNIT_BYTE - 1;
    long long tmp = n;

    if (base == BASE_DECIMAL)
    {
        while (tmp > 0)
        {
            tmp /= 1000;
            unit++;
        }
    }
    else if (base == BASE_BINARY)
    {
        while (tmp > 0)
        {
            tmp /= 1024;
            unit++;
            if (unit == DIGIT_UNIT_KILOBYTE)
            {
                unit = DIGIT_UNIT_KIBIBYTE;
            }
        }
    }

    return unit_format_custom (n, unit);
}

int main(int argc, char **argv)
{
    printf ("%s
", unit_format_custom (25678, DIGIT_UNIT_KILOBYTE));
    printf ("%s
", unit_format (4096, BASE_BINARY));
    printf ("%s
", unit_format (4096, BASE_DECIMAL));
    printf ("%s
", unit_format (8192, BASE_BINARY));
    printf ("%s
", unit_format (8192, BASE_DECIMAL));
    return 0;
}
原文地址:https://www.cnblogs.com/the-capricornus/p/4211871.html