Search code examples
c++boostc++14

Format negative number with boost


I want to get a certain UTC offset received in minutes using boost::format in the following format:

120: +0200
-120: -0200

I used the following function for this:

void printData(const int dat)
{
    std::string data;
    if (dat >= 0)
    {
        data = (boost::format("+%02d%02d") % (dat/60) % (dat%60)).str();
    }
    else
    {
        data = (boost::format("%03d%02d") % (dat/60) % (dat%60)).str();
    }
    
    std::cout<<" " << data << "\n";
}

It should work for the following cases:

    // 1: 0-10  (+, -)
    // 1.1 fix hour
       std::cout<<"1:\n";
       std::cout<<"1.1:\n";
       printData(540); // +9 hours -> OK (+0900)
       printData(-540); // -9 hours -> OK (-0900)
       printData(600); // +10 hours -> OK (+1000)
       printData(-600); // -10 hours -> OK (-1000)
    // 1.2 half hour
        std::cout<<"1.2:\n";
        printData(570); // +9:30 hours -> OK (+0930)
        printData(-570); // -9:30 hours -> NOK -> (-09-30) // -0930 should be
    // 1.3 three quarte an hour
        std::cout<<"1.3:\n";
        printData(585); // +9:40 hours -> OK (+0945)
        printData(-585); // -9:45 hours -> NOK -> (-09-40) // -0945 should be
        std::cout<<"\n";

    std::cout<<"\n2:\n";
    // 2: 11-14 (+, -):
    // 2.1 fix hour
        std::cout<<"2.1:\n";
       printData(660); // +11 hours -> OK (+1100)
       printData(-660); // -11 hours -> OK (-1100)
    // 2.2 half hour
         std::cout<<"2.2:\n";
        printData(690); // +11:30 hours -> OK (+1130)
        printData(-690); // -11:30 hours -> NOK -> (-11-30) // -1130 should be
    // 2.3 three quarte an hour
        std::cout<<"2.3:\n";
        printData(705); // +11:45 hours -> OK (+1145)
        printData(-705); // -11:45 hours -> NOK -> (-11-45) // -1145 should be
        std::cout<<"\n";

Is possible to use boost::format to support all the cases? https://godbolt.org/z/5Mfs5Yh6z


Solution

  • You can use a temp variable for the sign and negate dat when negative. So, you can use the same boost::format line for both cases (less repetitive code):

    void printData(int dat)
    {
        char sign = '+';
        if (dat < 0)
        {
            dat = -dat;
            sign = '-';
        }
        std::string data = (boost::format("%c%02d%02d") % sign % (dat/60) % (dat%60)).str();
        std::cout<<" " << data << "\n";
    }
    

    https://godbolt.org/z/7YPbejsj3

    Even easier is to use std::printf from iostream, which has the same syntax as the C version:

    void printData(int dat)
    {
        char sign = '+';
        if (dat < 0)
        {
            dat = -dat;
            sign = '-';
        }
        std::printf("%c%02d%02d\n", sign, dat/60, dat%60);
    }
    

    https://godbolt.org/z/Ea76P5srs