Convert int to Glib::ustring w/o stringstream

1.5k views Asked by At

I need to convert an integer to a Glib::ustring, but I don't want to use stringstream. Not that there's anything inherently WRONG with stringstream, but I don't want yet another library just to accomplish such a simple task.

My first instinct is to write a function with a big 'ol if-statement, or use an array of characters for each digit, but there has to be something cleaner. Is there any alternative?

2

There are 2 answers

4
user657267 On BEST ANSWER

Glib::ustring provides a format static function that simply forwards whatever you throw at it (up to 8 arguments, no variadic template yet it seems) to a stringstream and returns the formatted string:

Glib::ustring text = Glib::ustring::format(123456);

Since c++11 the standard library also has an overloaded to_string method for converting integers and floats

Glib::ustring text(std::to_string(123456));
1
CodeMouse92 On

EDIT: This method is intended to avoid STL completely, for cases/libraries where that is necessary. However, Glib::ustring does indeed use STL anyway, just FYI. If you're using some other custom string class, or just feel like a smart aleck with Glib, this might still come in handy.

Yes, it is actually possible, though it does require a custom function. This works quite well thus far, and doesn't require any other libraries, besides the obvious Glib::ustring. You can substitute any other char-supporting string class, and just adjust the Glib::ustring lines accordingly.

Glib::ustring int_to_ustring(int num)
{
    bool neg = false;
    int sub = 0;
    char digit;
    //This is what we'll return.
    Glib::ustring str = "";

    //If number is 0, the math won't work. Just return the string "0".
    if(num == 0)
    {
        str = "0";
        return str;
    }
    //Else, if the number is negative...
    else if(num < 0)
    {
        //Store that information and make the number positive.
        neg = true;
        num = abs(num);
    }

    //Determine place value.
    int pv = 0;
    do
    {
        //Divide by a power of ten and trunicate decimal.
        sub = num / pow(10, pv);
        //Increase pv.
        pv++;
    }
    //If we got zero, then we're too large.
    while(sub != 0);

    //NOTE: The above seems to make the place value two-too-large?

    //Loop backwards through the place values.
    for(pv; pv >= 0; pv--)
    {
        sub = num / pow(10, pv);
        num -= sub*(pow(10, pv));

        if(sub < 0 || sub > 10)
        {
            //Throw an error. I'm just using this as a placeholder.
            std::cout << "Something went really weird." << std::endl;
        }

        //The char code for the digit is always 48 more than the digit.
        digit = sub + 48;
        //If this isn't a leading zero...
        if(!(str == "" && digit == '0'))
        {
            //This is the best way to push a char to a ustring.
            str.insert(str.end(), digit);
        }
    }

    //If that number was negative, insert the negative sign.
    if(neg)
        str.insert(str.begin(), '-');

    return str;
}

(By the by, suggested improvements are welcomed! I'm hoping to make this more efficient yet.)