C++存储数据单位转换输出字符串

68 篇文章 0 订阅
1 篇文章 0 订阅

C++封装存储数据单位转换, 方便将输入数据以指定方式输出

main.cpp

#include <wtypesbase.h>
#include <string>
#include <vector>
#include <tchar.h>

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

// 数据单位
enum eUnitType
{
    eUT_Auto,   // 自动
    eUT_b,      // (2 ^ 000) * 8 Bit
    eUT_Kb,     // (2 ^ 010) * 8 Bit
    eUT_Mb,     // (2 ^ 020) * 8 Bit
    eUT_Gb,     // (2 ^ 030) * 8 Bit
    eUT_Tb,     // (2 ^ 040) * 8 Bit
    eUT_Pb,     // (2 ^ 050) * 8 Bit
    eUT_Eb,     // (2 ^ 060) * 8 Bit
    eUT_Zb,     // (2 ^ 070) * 8 Bit
    eUT_Yb,     // (2 ^ 080) * 8 Bit
    eUT_Bb,     // (2 ^ 090) * 8 Bit
    eUT_Nb,     // (2 ^ 100) * 8 Bit
    eUT_Db,     // (2 ^ 110) * 8 Bit
    eUT_Cb,     // (2 ^ 120) * 8 Bit
    eUT_Xb,     // (2 ^ 130) * 8 Bit

    eUT_B,      // Byte          2 ^ 000 Byte
    eUT_KB,     // Kilobyte      2 ^ 010 Byte 
    eUT_MB,     // Megabyte      2 ^ 020 Byte 
    eUT_GB,     // Gigabyte      2 ^ 030 Byte 
    eUT_TB,     // Terabyte      2 ^ 040 Byte 
    eUT_PB,     // Petabyte      2 ^ 050 Byte 
    eUT_EB,     // Exabyte       2 ^ 060 Byte 
    eUT_ZB,     // Zettabyte     2 ^ 070 Byte 
    eUT_YB,     // Yottabyte     2 ^ 080 Byte 
    eUT_BB,     // Brontobyte    2 ^ 090 Byte 
    eUT_NB,     // NonaByte      2 ^ 100 Byte 
    eUT_DB,     // DoggaByte     2 ^ 110 Byte 
    eUT_CB,     // corydonbyte   2 ^ 120 Byte 
    eUT_XB,     // Xerobyte      2 ^ 130 Byte
    eUT_Max
};

typedef struct _DATA_UNIT_INFO
{
    double value;           // 数值
    eUnitType eUnit;        // 单位
    _tstring strUnitStr;    // 单位字符串
    _tstring strOutput;    // 内容(数值 + 单位字符串)
}DATA_UNIT_INFO;

DATA_UNIT_INFO FormatByteSize(
    double nBytesSize,                                      // 输入值
    eUnitType eSrcUnit = eUnitType::eUT_Auto,               // 原始单位
    eUnitType eDestUnit = eUnitType::eUT_Auto,              // 目标单位
    bool fHasUnits = true,                                  // 结果字符串数值添加单位
    bool fSpace = true,                                     // 结果字符串数值与单位之间添加空格
    int nInteger = 1,                                       // 整数部分长度
    int nPrecision = 3                                      // 小数部分长度
);

void ConsoleOutput(LPCTSTR pFormat, ...);

int main()
{
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_B,  eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_KB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_MB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_GB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_TB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_PB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_EB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_ZB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_YB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_BB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_NB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_DB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_CB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());
    ConsoleOutput(_T("%s\r\n"), FormatByteSize(1, eUnitType::eUT_XB, eUnitType::eUT_Auto, true, true, 0, 1).strOutput.c_str());

    return 0;
}

DATA_UNIT_INFO FormatByteSize(
    double nBytesSize,
    eUnitType eSrcUnit/* = eUnitType::eUT_Auto*/,
    eUnitType eDestUnit/* = eUnitType::eUT_Auto*/,
    bool fHasUnits/* = true*/,
    bool fSpace/* = true*/,
    int nInteger/* = 1*/,
    int nPrecision/* = 3*/
)
{
    TCHAR szFormatBuf[MAX_PATH] = { 0 };
    TCHAR szResultBuf[MAX_PATH] = { 0 };
    DATA_UNIT_INFO dataUnitInfo;
    bool fSrcBit = false;
    bool fDestBit = false;

    LPCTSTR strUnitByteName[] = {
        _T("B"),
        _T("KB"),
        _T("MB"),
        _T("GB"),
        _T("TB"),
        _T("PB"),
        _T("EB"),
        _T("ZB"),
        _T("YB"),
        _T("BB"),
        _T("NB"),
        _T("DB"),
        _T("CB"),
        _T("XB"),
    };

    LPCTSTR strUnitBitName[] = {
        _T("b"),
        _T("Kb"),
        _T("Mb"),
        _T("Gb"),
        _T("Tb"),
        _T("Pb"),
        _T("Eb"),
        _T("Zb"),
        _T("Yb"),
        _T("Bb"),
        _T("Nb"),
        _T("Db"),
        _T("Cb"),
        _T("Xb"),
    };

    // 原始单位 比特 -> 字节
    if (eSrcUnit >= eUnitType::eUT_b && eSrcUnit < eUnitType::eUT_B)
    {
        fSrcBit = true;
        eSrcUnit = (eUnitType)(eSrcUnit + (eUnitType::eUT_B - eUnitType::eUT_b));
    }

    // 目标单位 比特 -> 字节
    if (eDestUnit >= eUnitType::eUT_b && eDestUnit < eUnitType::eUT_B)
    {
        fDestBit = true;
        eDestUnit = (eUnitType)(eDestUnit + (eUnitType::eUT_B - eUnitType::eUT_b));
    }

    // 原始单位转换
    for (int i = eUnitType::eUT_B; i < eSrcUnit; i++)
    {
        nBytesSize *= 1024.0f;
    }

    // 自动
    int nUnitTypeIndex = eUnitType::eUT_B;
    if (eUnitType::eUT_Auto == eDestUnit)
    {
        double nCurUnitSize = 1.0f;
        double nNextUnitSize = 1024.0f;
        int nUnitTypeMaxIndex = eUnitType::eUT_Max - 1;
        for (int i = 0; i < _countof(strUnitByteName) && nUnitTypeIndex < nUnitTypeMaxIndex; i++)
        {
            if ((nBytesSize >= nCurUnitSize && nBytesSize < nNextUnitSize) || 0 == nNextUnitSize || 0 == nBytesSize)
            {
                break;
            }

            nCurUnitSize *= 1024.0f;
            nNextUnitSize *= 1024.0f;
            nUnitTypeIndex++;
        }
        eDestUnit = (eUnitType)nUnitTypeIndex;
    }

    {
        ::_stprintf_s(szFormatBuf, _countof(szFormatBuf), _T("%%%d.%dlf"), nInteger + nPrecision + 1, nPrecision);
        double fUnitSize = 1.0f;
        for (int i = eUnitType::eUT_B; i < eDestUnit; i++)
        {
            fUnitSize *= 1024.0f;
        }

        if (fSrcBit)
        {
            fUnitSize *= 8.0f;
        }

        if (fDestBit)
        {
            nBytesSize *= 8.0f;
        }

        double lfResult = nBytesSize / fUnitSize;
        ::_stprintf_s(szResultBuf, _countof(szResultBuf), szFormatBuf, lfResult);
        dataUnitInfo.strOutput = szResultBuf;
        dataUnitInfo.value = lfResult;

        if (fHasUnits)
        {
            if (fSpace)
            {
                dataUnitInfo.strOutput += _T(" ");
            }

            if (fDestBit)
            {
                dataUnitInfo.strOutput += strUnitBitName[eDestUnit - eUnitType::eUT_B];
                dataUnitInfo.strUnitStr = strUnitBitName[eDestUnit - eUnitType::eUT_B];
                dataUnitInfo.eUnit = (eUnitType)(eDestUnit + (eUnitType::eUT_B - eUnitType::eUT_b));
            }
            else
            {
                dataUnitInfo.strOutput += strUnitByteName[eDestUnit - eUnitType::eUT_B];
                dataUnitInfo.strUnitStr = strUnitByteName[eDestUnit - eUnitType::eUT_B];
                dataUnitInfo.eUnit = eDestUnit;
            }
        }
    }

    return dataUnitInfo;
}

void ConsoleOutput(LPCTSTR pFormat, ...)
{
    size_t nCchCount = MAX_PATH;
    _tstring strResult(nCchCount, 0);
    va_list args;

    va_start(args, pFormat);

    do
    {
        //格式化输出字符串
        int nSize = _vsntprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
        if (-1 != nSize)
        {
            HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
            ::WriteConsole(console, strResult.c_str(), nSize, NULL, NULL);
            break;
        }

        //缓冲大小超限终止
        if (nCchCount >= INT32_MAX)
        {
            break;
        }

        //重新分配缓冲
        nCchCount *= 2;
        strResult.resize(nCchCount);

    } while (true);

    va_end(args);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值