boost::lexical_cast int to string padding with zeros - c++

I need to create files with generated names. I use boost::lexical_cast to transform integers to std::string. Is it a possibility to get string with padding zeros;
I have no c++11 tools, just everything that MSVS 2008 supports.
Example :
int i = 10;
std::string str = boost::lexical_cast<std::string>(i);
// str = "10"
// expect str = "000010"
p.s. don't suggest to use sprintf please.

Why boost::lexical_cast? Use std::stringstream
std::ostringstream ss;
ss << std::setw(6) << std::setfill('0') << i;
const std::string str = ss.str();

You could use std::ostringstream with the normal stream manipulators for formatting.

Related

Converting int to string and adding to an existin string in c++

I was wondering how I could convert an int to a string and then add it to an existin string. i.e.
std::string s = "Hello";
//convert 1 to string here
//add the string 1 to s
I hope I'm making sense. Thank you very much in advance for any answer.
If the number you want to append is an integer or floating point variable, then use std::to_string and simply "add" it:
int some_number = 123;
std::string some_string = "foo";
some_string += std::to_string(some_number);
std::cout << some_string << '\n';
Should output
foo123
The "modern" way is to use std::to_string(1). In fact, various overloads of std::to_string exist for different number types.
Putting this together you can write std::string s = "Hello" + std::to_string(1);
Alternatively you can use std::stringstream which can be faster due to fewer string concatenation operations which can be expensive:
std::stringstream s;
s << "Hello" << 1;
// s.str() extracts the string

c++ custom string format using stringstreams

I am trying to use the new stringstreams method to convert certain float+int combination into certain format but trying to see if there is any better way to handle this:
Now using //string String = static_cast( &(ostringstream() << Number) )->str(); kind of mode - How can I get this stored into a string form of the format - "1.10(3)". Precision is equal to decimals. The catch here is none of these values are constants. Even if the solution can't be an in-line function or stringstreams - it's fine as long as it's generic enough. Also note that in the end the plan is to use this string into GDI text string.
Thanks in advance - if any one can help.
Here is my current sample code(and looking for an alternate efficient way to get this done):
string Convert(float number,int decimals)
{
std::ostringstream buff;
buff<<setprecision(decimals)<<fixed<<number;
return buff.str();
}
float f=1.1; // this can have any values from 1,1.5 or 1.52
int decimals=2; //dynamic number - calculated by other means - not a fixed number
int i=3; // some dynamic number as well - calculated by other means
string s=Convert(f,decimals)+"("+Convert(i,0)+")"; // output - 1.10(3)
You can use std::fixed, std::setprecision, std::setw and std::setfill defined in <iomanip> :
float f=1.1;
int decimals=2;
int i=3;
ostringstream ss;
ss << std::fixed << std::setprecision(decimals) << f << '(' << i << ')';
string str = ss.str();
Which outputs :
1.10(3)
You can also configure the stringstream and keep this configuration :
ostringstream ss;
ss.precision(5);
ss.setf(std::ios::fixed);
EDIT
You can still do this in one line if you really want to :
string str = ((ostringstream&)(ostringstream() << fixed << setprecision(decimals) << f << '(' << i << ')')).str();
If you want a LPCWSTR (const wchar_t *) instead of a LPCSTR (const char*) you should use wstringstream instead of stringstream.
ostringstream ss;
string str = ss.str();
LPCSTR* c_str = str.c_str();
wostringstream wss;
wstring wstr = wss.str();
LPCWSTR* wc_str = wstr.c_str();
If you want a LPCTSTR (LPCSTR or LPCWSTR if UNICODE is defined), you can use some typedef like this :
typedef std::basic_string<TCHAR> tstring;
typedef std::basic_ostringstream<TCHAR , std::char_traits<TCHAR> > tstringstream;
tostringstream tss;
tstring tstr = tss.str();
LPCTSTR* tc_str = tstr.c_str();
TCHAR is a char * if UNICODE is not defined in your project and a wchar_t * if UNICODE is defined.

Getting a buffer into a stringstream in hex representation:

If I had a buffer like:
uint8_t buffer[32];
and it was filled up completely with values, how could I get it into a stringstream, in hexadecimal representation, with 0-padding on small values?
I tried:
std::stringstream ss;
for (int i = 0; i < 32; ++i)
{
ss << std::hex << buffer[i];
}
but when I take the string out of the stringstream, I have an issue: bytes with values < 16 only take one character to represent, and I'd like them to be 0 padded.
For example if bytes 1 and 2 in the array were {32} {4} my stringstream would have:
204 instead of 2004
Can I apply formatting to the stringstream to add the 0-padding somehow? I know I can do this with sprintf, but the streams already being used for a lot of information and it would be a great help to achieve this somehow.
#include <sstream>
#include <iomanip>
std::stringstream ss;
ss << std::hex << std::setfill('0');
for (int i = 0; i < 32; ++i)
{
ss << std::setw(2) << static_cast<unsigned>(buffer[i]);
}
Look at the stream modifiers: std::setw and std::setfill. It will help you.
You can do this with C++20 std::format:
std::stringstream ss;
for (int i = 0; i < 32; ++i) {
ss << std::format("{:02}", buffer[i]);
}
Until std::format is widely available you can use the {fmt} library, std::format is based on. {fmt} also provides the join function that makes this even easier (godbolt):
std::string s = fmt::format("{:02}", fmt::join(buffer, ""));
Disclaimer: I'm the author of {fmt} and C++20 std::format.

String concatenation in C++ problem

everybody I have problem with string concatenation in C++, here is my code
map<double, string> fracs;
for(int d=1; d<=N; d++)
for(int n=0; n<=d; n++)
if(gcd(n, d)==1){
string s = n+"/"+d;// this does not work in C++ but works in Java
fracs.insert(make_pair((double)(n/d), s));
}
How can I fix my code?
Try like this.
stringstream os;
os << n << "/" << d;
string s =os.str();
In C++ you have to convert an int to a string before you can concatenate it with another string using the + operator.
See Easiest way to convert int to string in C++.
Use streams, in your case, a stringstream:
#include <sstream>
...
std::stringstream ss;
ss << n << '/' << d;
Later, when done with your work, you can store it as an ordinary string:
const std::string s = ss.str();
Important (side-) note: Never do
const char *s = ss.str().c_str();
stringstream::str() produces a temporary std::string, and according to the standard, temporaries live until the end of the expression. Then, std::string::c_str() gives you a pointer to a null-terminated string, but according to The Holy Law, that C-style-string becomes invalid once the std::string (from which you receved it) changes.
It might work this time, and next time, and even on QA, but explodes right in the face of your most valuable customer.
The std::string must survive until the battle is over:
const std::string s = ss.str(); // must exist as long as sz is being used
const char *sz = s.c_str();
n and d are integers. Here is how you can convert integer to string:
std::string s;
std::stringstream out;
out << n << "/" << d;
s = out.str();
You could use a stringstream.
stringstream s;
s << n << "/" << d;
fracs.insert(make_pair((double)n/d, s.str()));
No one has suggested it yet but you can also take a look at boost::lexical_cast<>.
While this method is sometimes criticized because of performance issues, it might be ok in your situation, and it surely makes the code more readable.
Unlike in Java, in C++ there is no operator+ that explicitly converts a number to a string. What is usually done in C++ in cases like this is...
#include <sstream>
stringstream ss;
ss << n << '/' << d; // Just like you'd do with cout
string s = ss.str(); // Convert the stringstream to a string
I think sprintf(), which is a function used to send formatted data to strings, would be a much clearer way to do it. Just the way you would use printf, but with the c-style string type char* as a first(additional) argument:
char* temp;
sprint(temp, "%d/%d", n, d);
std::string g(temp);
You could check it out at http://www.cplusplus.com/reference/cstdio/sprintf/

Equivalent of %02d with std::stringstream?

I want to output an integer to a std::stringstream with the equivalent format of printf's %02d. Is there an easier way to achieve this than:
std::stringstream stream;
stream.setfill('0');
stream.setw(2);
stream << value;
Is it possible to stream some sort of format flags to the stringstream, something like (pseudocode):
stream << flags("%02d") << value;
You can use the standard manipulators from <iomanip> but there isn't a neat one that does both fill and width at once:
stream << std::setfill('0') << std::setw(2) << value;
It wouldn't be hard to write your own object that when inserted into the stream performed both functions:
stream << myfillandw( '0', 2 ) << value;
E.g.
struct myfillandw
{
myfillandw( char f, int w )
: fill(f), width(w) {}
char fill;
int width;
};
std::ostream& operator<<( std::ostream& o, const myfillandw& a )
{
o.fill( a.fill );
o.width( a.width );
return o;
}
You can use
stream<<setfill('0')<<setw(2)<<value;
You can't do that much better in standard C++. Alternatively, you can use Boost.Format:
stream << boost::format("%|02|")%value;
Is it possible to stream some sort of format flags to the stringstream?
Unfortunately the standard library doesn't support passing format specifiers as a string, but you can do this with the fmt library:
std::string result = fmt::format("{:02}", value); // Python syntax
or
std::string result = fmt::sprintf("%02d", value); // printf syntax
You don't even need to construct std::stringstream. The format function will return a string directly.
Disclaimer: I'm the author of the fmt library.
i think you can use c-lick programing.
you can use snprintf
like this
std::stringstream ss;
char data[3] = {0};
snprintf(data,3,"%02d",value);
ss<<data<<std::endl;