patterncppMinor
Integer to string or wstring converter
Viewed 0 times
converterstringintegerwstring
Problem
I can't use
I am not sure how efficient it is. Is there any solution that is more efficient?
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
Advantages:
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.