HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Integer to string or wstring converter

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
converterstringintegerwstring

Problem

I can't use std::to_string and std::to_wstring function, so I have written a converter:

///@struct ParseInt
///Contains function that parses integer.
template struct ParseInt{
    static std::basic_string toString(int x);
};

///Converts integer to std::string
///@param x the integer to convert
///@return std::string from the integer
template<> inline std::string ParseInt::toString(int x){
    int length = 2; //most ints coming here are 2 digits long.
    char* buf = 0;
    do{
        delete[] buf;
        buf = new char[++length + 1];
    }while(sprintf(buf, "%d", x)  inline std::wstring ParseInt::toString(int x){
    int length = 2; //most ints coming here are 2 digits long.
    wchar_t* buf = 0;
    do{
        delete[] buf;
        buf = new wchar_t[++length + 1];
    }while(swprintf(buf, length + 1, L"%d", x) < 0);
    std::wstring str(buf);
    delete[] buf;
    return str;
}


I am not sure how efficient it is. Is there any solution that is more efficient?

Solution

I am not sure how efficient it is. Is there any solution that is more efficient?

Very inefficient.

First, you allocate buffers with new/delete. You should not do that. Second, you allocate in a loop. You shouldn't do that either.

Consider this code instead (function renamed to to_string, as what you do is not parsing - parsing would be the inverse operation - taking a string and extracting an integer from it):

auto print(char * buffer, int x)
{
    return sprintf(buffer, "%d", x);     
}

auto print(wchar_t * buffer, int x)
{
    return wsprintf(buffer, "%d", x);     
}

///Converts integer to std::string
///@param x the integer to convert
///@return std::string/std::wstring from the integer
template,
    typename A=std::allocator>
std::basic_string to_string(int x)
{
    C buffer[ 64 ] = { 0 }; // no new/delete required
                            // no loop required
                            // max int on 32bit architectures is
                            // 2,147,483,647; 64 bytes is "big enough"

    auto written = print(buffer, "%d", x);
    assert(written > 0); // should always be true
    return std::basic_string{ buffer, buffer + written };
}


Advantages:

  • there is no code repetition (easier to maintain)



  • efficiency is linear in to_string (no loops)



  • code is simpler and more straight-forward

Code Snippets

auto print(char * buffer, int x)
{
    return sprintf(buffer, "%d", x);     
}

auto print(wchar_t * buffer, int x)
{
    return wsprintf(buffer, "%d", x);     
}

///Converts integer to std::string
///@param x the integer to convert
///@return std::string/std::wstring from the integer
template<typename C,
    typename T=std::char_traits<C>,
    typename A=std::allocator<C>>
std::basic_string<C,T,A> to_string(int x)
{
    C buffer[ 64 ] = { 0 }; // no new/delete required
                            // no loop required
                            // max int on 32bit architectures is
                            // 2,147,483,647; 64 bytes is "big enough"

    auto written = print(buffer, "%d", x);
    assert(written > 0); // should always be true
    return std::basic_string<C,T,A>{ buffer, buffer + written };
}

Context

StackExchange Code Review Q#147078, answer score: 3

Revisions (0)

No revisions yet.