Use stream instead of snprintf - c++

I'm not fairly familiar in C++ stream API and I want to convert a C code using stream in C++,
char sHex[20] = {0};
int numid = 2;
snprintf( sHex, sizeof(sHex) - 1, "%X", numId );

stringstream ss;
ss << uppercase << hex << numId;
string res = ss.str();

Take a look at Understanding C++ Streams and Stream Buffers it may help you, like as helped me.

Related

boost::lexical_cast int to string padding with zeros

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.

Is these a way to set the output of printf to a string?

I need the output of printf("%02X", buffer[0]) to be put into a string.
In theory it would be something like:
string str = printf("%02X", buffer[0]) +printf("%02X", buffer[1]) +printf("%02X", buffer[2]) +printf("%02X", buffer[3]);
That, however, doesn't work and i can't figure out how to do it.
Any help is appreciated, Thanks.
Return value of printf is the number of characters written, use snprintf:
char s[BIG_ENOUGH];
snprintf(s, BIG_ENOUGH, "%02X %02X %02X %02X ", buffer[0],
buffer[1],
buffer[2],
buffer[3]);
std::string str(s);
Also, you can forget xprintf ways and use C++ streams:
std::ostringstream s;
s << std::hex;
for (int i=0; i<4; i++)
s << std::setfill('0') << std::setw(2) << buffer[i] << ' ';
std::string str(s.str());
As M M. wrote, sprintf is what you're looking for. Or better yet, use snprintf for added security against buffer overflows:
char s[SIZE];
snprintf(s, SIZE, "%02X", buffer[0]);
string str(s);
snprintf will never write more than SIZE bytes to s.
I have found that boost::format() is a great way to preserve printf() type formatting while outputting to a stream. Once you are using a stream, you can use std::ostringstream or someting similar to format in memory.

Equivalent of %05d with std::stringstream for negative numbers?

I'm trying to create a replacement for sprintfs' %05d behavior. Althought, I've found a similar question here on stackoverflow, the proposed solution there doesn't work for me when I'm testing with negative numbers.
Doing a "sprintf(buf, "%05d", -12)", I'm getting "-0012" back which looks nice.
Using stringstream, width and fill, I'm getting "00-12" which seams reasonable when looking at the docs from std::basic_ios::fill
The fill character is the character used by output insertion functions to fill spaces when padding results to the field width.
but doesn't look like something one could wish.
So I'm confused and don't know if I'm doing something obvious wrong or if width/fill from the std streams doesn't easily support this situation.
A compilable testcode can be found on codepad.
Here's an extract of the stream based conversion:
std::string NumberToString(const long iVal, const int iNumDigit)
{
std::stringstream ss;
if (iNumDigit >= 0) ss.fill(' ');
else if (iNumDigit < 0) ss.fill('0');
ss.width(std::abs(iNumDigit));
ss << iVal;
return ss.str();
}
EDIT1: Solution:
To match the std stream approach with printf formatting for %05d, jrok's solution can be used for the case with leading zeros. Here's the new function:
std::string NumberToString(const long iVal, const int iNumDigit)
{
std::stringstream ss;
if (iNumDigit >= 0) ss.fill(' ');
else if (iNumDigit < 0) { ss.fill('0'); ss.setf(std::ios::internal, std::ios::adjustfield); }
ss.width(std::abs(iNumDigit));
ss << iVal;
return ss.str();
}
Use stream manipulator std::internal.
It (along with std::left and std::right) lets you specify where the fill characters go. For example
std::cout << std::setw(5) << std::setfill('0') << std::internal << -1;
will print -0001.

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;