I think I read somewhere that if I pass a nullptr to std::strftime, the function would return the required buffer size. And indeed, the following code works perfectly well on numerous linux systems I've tried it on (not when compiled with VS though):
#include <iostream>
#include <ctime>
#include <string>
int main()
{
std::time_t time{};
std::tm const * ltime = std::localtime(&time);
const char * formatString = "%Y-%b-%d";
//allocate buffer of appropriate size
auto requiredSize = 1 + std::strftime(nullptr, 50, formatString, ltime);
std::cout << "Required buffer size:" << requiredSize << "\n";
//Format time to string
std::string buff(requiredSize, ' ');
std::strftime(&buff[0], requiredSize, formatString, ltime);
std::cout << buff << std::endl;
}
However, I was unable to find my original source or any other documentation that would specify this behavior. So my question is:
On which systems / compilers / standard library implementations (if any) is this a guaranteed behavior?
Where can I find the according documentation?
Edit: I added the C label, as I've seen the same result with equivalent C code and at least with gcc/g++ (or rather glibc/libstdc++) std::strftime is probably just an alias for the c-function strftime anyway.
As far as I can tell and as others have wrote in the comments, above code is most probably undefined behavior according to the ISO C or C++ standard and as far as my own experiments are concerned will crash when compiled with VS2015.
However, as far as glibc is concerned, #rici was spot on:
From the documentation of The GNU C Library:
If s is a null pointer, strftime does not actually write anything, but instead returns the number of characters it would have written.
Related
I have a simple variable:
float t = 30.2f;
How do I add it to a string?
char* g = "Temperature is " + h?
Any guaranteed way (I don't have Boost for instance, and unsure of what version of c++ I have) I can get this to work on a microcontroller?
For simple cases, you can just use the std::string class and the std::to_string function, which have both been part of C++ for a long time.
#include <string>
#include <iostream>
int main()
{
float t = 30.2;
std::string r = "Temperature is " + std::to_string(t);
std::cout << r;
}
However, std::to_string doesn't give you much control over the formatting, so if you need to specify a field width or a number of digits after the decimal point or something like that, it would be better to see lorro's answer.
If you have an incomplete implementation of the C++ standard library on your microcontroller so you can't use the functions above, or maybe you just want to avoid dynamic memory allocation, try this code (which is valid in C or C++):
float t = 30.2;
char buffer[80];
sprintf(buffer, "Temperature is %f.", t);
Note that buffer must be large enough to guarantee there will never be a buffer overflow, and failing to make it large enough could cause crashes and security issues.
std::ostringstream oss;
oss << t;
std::string s = "Temperature is " + oss.str();
Then you can use either the string or the c_str() of it (as const char*).
If, for some reason, you don't have standard library, you can also use snprintf() et. al. (printf-variants), but then you need to do the buffer management yourself.
For the sake of completeness, C++20 introduces std::format for fluent string formatting of this sort:
#include <format>
#include <iostream>
#include <string>
int main() {
float t = 30.2f;
std::string s = std::format("Temperature is {}!\n", t);
std::cout << s;
}
Do note that compiler support for the format library is still underway. GCC does not yet support it, and Clang only has experimental support1 in 14.0+.
1 requires LLVM to be compiled with -DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON
I have a given buffer of characters (maybe even the buffer backing an std::string, but never mind that). I want to print into that buffer using an std::ostream, i.e. I want to be able to write:
span<char> my_buffer = get_buffer();
auto my_os = /* magic */;
static_assert(
std::is_base_of<std::basic_ostream<char>,decltype(my_os)>::value,
"magic failed");
my_os << "hello" << ',' << 123 << '\0';
std::cout << my_buffer << '\n';
and get:
hello,123
on the standard output.
Note: C++11 if possible, and please mention the language standard you're using. (And yes, I know C++11 doesn't have spans.)
(Thank #BoP and #T.C. for the two parts of this solution)
This can be done... if you're willing to use a deprecated C++ construct: std:ostrstream.
#include <strstream>
#include <iostream>
int main() {
const size_t n = 20;
char my_buffer[n];
std::ostrstream my_os(my_buffer, n);
my_os << "hello" << ',' << 123 << '\0';
std::cout << my_buffer << '\n';
}
Notes about this code:
It works (GodBolt)
It is valid C++98! ... of course I had to let go of std::span, auto type inference etc. It's also valid C++11 and later standards.
This will construct an std::strstreambuf, which is what an std::ostrstream uses directly, from your buffer of chars.
(see this on GodBolt)
Unfortunately, with the deprecation of std::ostrstream, we were left with no fully-valid alternative up to, and including, C++20. You would need to implement a custom std::basic_streambuf, and assign it to an std::ostream. :-(
But in C++23 - you are luck! The standard library does offer exactly what you asked for: std::spanstream: A std::ostream backed by a span of char's which it is given at construction.
I have a code in C++ that's suppose to work on Linux and Windows.
Part of the code includes using vsnprintf in order to get a string using a format string and params.
I notices that whenever the format string contains %p the results are different on Linux and Windows - Windows doesn't prefix the result with 0x while linux does, and also windows uses uppercase for the letters of the address while Linux uses lowercase.
I couldn't find flags to make the two versions be identical.
My preference is to make the Linux version behave like the Windows one (since the Windows code is the original so that's how the program is expected to behave).
And if it's not possible to change the behavior of vsnprintf in Linux i would like a method to "fix" the strings that contain %p after vsnprintf outputs them (in an efficient way).
The string %p prints is implementation defined. That's why the behaviour is different on Linux and Windows. If you wanted consistent behaviour, you'd have to implement your own version.
Using uintptr_t, we can have an integer that can hold a pointer. So we can reinterpret_cast the pointer into it. Note that, although the conversion will succeed, it's not specified what the value will hold.
Then, we can print the integer as hex, either using std::hex or the appropriate format macro constant:
auto* myPointer = ...;
std::cout << std::hex << reinterpret_cast<std::uintptr_t>(myPointer) << '\n';
std::printf("%" PRIxPTR "\n", reinterpret_cast<std::uintptr_t>(myPointer));
Demo
The exact formatting would be up to you.
As Justin's answer suggests, you can convert the pointer to uintptr_t and format it as you like. This is likely to be 99% portable -- and since you're probably concerned with just Linux and Windows, that's probably good enough. (It can fail on a system where no integer type is big enough to hold a pointer value without loss of information. Such a system won't define uintptr_t. You're unlikely to encounter such a system.)
Another approach is to format the pointer as a string using a %p format, and then manipulate the resulting string to get the consistent results you want. It probably makes sense to create a function that takes a void* argument and returns a std::string.
Here's my attempt (I make no claim that this is good C++ code). It deletes a leading 0x or 0X if it exists, and it maps all remaining characters to upper case.
Tweak the for loop if you don't have a C++11 compiler.
#include <iostream>
#include <string>
#include <cstdio>
#include <cctype>
std::string hex(void* ptr) {
const int big_enough = 100;
char s[big_enough];
std::snprintf(s, sizeof s, "%p", ptr);
std::string result = s;
std::string prefix = result.substr(0, 2);
if (prefix == "0x" || prefix == "0X") {
result = result.substr(2);
}
for (auto &&c : result) {
c = std::toupper((unsigned char)c);
}
return result;
}
int main() {
int n;
int *ptr = &n;
std::printf("Using %%p: %p\n", (void*)ptr);
std::cout << "Using hex(): " << hex((void*)ptr) << "\n";
}
The output on my Linux system is:
Using %p: 0x7ffd6e8ca884
Using hex(): 7FFD6E8CA884
I am relatively new to the C++ world.
I know std::cout is used for console output in C++. But consider the following code in C :
#include<stdio.h>
int main(){
double dNum=99.6678;
printf("%.02lf",dNum);
//output: 99.67
return 0;
}
How do I achieve the similar formatting of a double type value upto 2 decimal places using cout in C++ ?
I know C++ is backward compatible with C. But is there a printf() equivalent in C++ if so, then where is it defined ?
This is what you want:
std::cout << std::fixed << std::setprecision(2);
std::cout << dNum;
and don't forget to :
#include <iostream>
#include <iomanip>
There is no equivalent. It is a pain using cout for formatted output.
All suggested solutions calling setprecision and similar are awfull when using long formats.
boost::format does not support some very nice features. Incompatibilities with printf. I still use printf because it is unbeatable.
If you want to use printf like formatting you should probably use snprintf (or build an allocating variant of that on top of that). Note that sprintf requires you to be able to guarantee that the result will not overrun the buffer you have to keep defined behaviour. With snprintf on the other hand can guarantee that it will not overrun the buffer since you specifiy the maximal number of characters that will be written to the string (it will instead truncate the output).
You could even build something that can directly be fed to an ostream on top of snprintf by automatically allocate the buffer and place in an object that on destruction free that memory. This in addition with a method to feed the object to an ostream would finish it off. Something like (with room for improvements):
struct Format {
char buf[999];
Format(fmt, ...) {
va_list ap;
va_start(fmt, ap);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
}
}
ostream& operator<< (ostream& os, Format const& str);
then you use this as:
cout << Format("The answer is %d", 42) << endl;
If you're using the GNU libraries you could of course use printf directly since cout and stdout are the same object then. Otherwise you should probably avoid mixing stdio and iostreams as there is no guarantee that these are synchronized with each other.
If you really want to reuse the same formatting techniques as in C, you may use Boost::format, which does exactly that:
cout << boost::format("%.02lf") % dNum;
But is there a printf() equivalent in C++ if so, then where is it defined?
There is a standards proposal P0645 to add a similar formatting facility to C++. In the meantime you can use the {fmt} library that implements this proposal and more:
#include <fmt/core.h>
int main()
fmt::print("{:.02f}", 99.6678);
}
P0645 and {fmt} use Python-like format string syntax which is similar to printf's but uses {} as delimiters instead of %.
Also the type information is preserved so you don't need l or other noisy specifiers.
Save your program as CPP and run it.
It runs and prints the answer.
Because C++ also has the printf() and scanf() like C.
You can also use sprintf in C++ to 'print' into a string and then cout that string. This strategy leverages your experience with printf-style formatting.
To output a value to the console using C++, you need the global ostream object cout and the << operator. endl is another global ostream object used as line break.
All are defined in the <iostream> header file. You can also use various formatting flags to control the presentation of the output...
#include<iostream>
using namespace std;
int main() {
double dNum = 99.6678;
cout << dNum;
cout.setf(ios::scientific, ios::floatfield); // format into scientific notation
cout << dNum;
cout.precision(8); // change precision
cout << dNum;
system("pause");
return 0;
}
The functional equivalent of your printf() call, using std::cout, is
std::cout << fixed << setprecision(2) << dNum;
It is necessary to #include <iomanip> and <iostream>.
The printf() equivalent in C++ is std::printf(), declared in <cstdio>.
Also, thanks to backward compatibility to C - specifically C++98 was required to maximise backward compatiblility to C89 - C's printf() declared in <stdio.h> is also available in C++. Note, however, that <stdio.h> is deprecated (tagged for removal from a future version of the C++ standard). Also, not all features of printf() introduced in C99 (the 1999 C standard) or later are necessarily supported in C++.
This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 7 years ago.
I was wondering if there was an alternative to itoa() for converting an integer to a string because when I run it in visual Studio I get warnings, and when I try to build my program under Linux, I get a compilation error.
In C++11 you can use std::to_string:
#include <string>
std::string s = std::to_string(5);
If you're working with prior to C++11, you could use C++ streams:
#include <sstream>
int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
Taken from http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/
boost::lexical_cast works pretty well.
#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
std::string foo = boost::lexical_cast<std::string>(argc);
}
Archeology
itoa was a non-standard helper function designed to complement the atoi standard function, and probably hiding a sprintf (Most its features can be implemented in terms of sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html
The C Way
Use sprintf. Or snprintf. Or whatever tool you find.
Despite the fact some functions are not in the standard, as rightly mentioned by "onebyone" in one of his comments, most compiler will offer you an alternative (e.g. Visual C++ has its own _snprintf you can typedef to snprintf if you need it).
The C++ way.
Use the C++ streams (in the current case std::stringstream (or even the deprecated std::strstream, as proposed by Herb Sutter in one of his books, because it's somewhat faster).
Conclusion
You're in C++, which means that you can choose the way you want it:
The faster way (i.e. the C way), but you should be sure the code is a bottleneck in your application (premature optimizations are evil, etc.) and that your code is safely encapsulated to avoid risking buffer overruns.
The safer way (i.e., the C++ way), if you know this part of the code is not critical, so better be sure this part of the code won't break at random moments because someone mistook a size or a pointer (which happens in real life, like... yesterday, on my computer, because someone thought it "cool" to use the faster way without really needing it).
Try sprintf():
char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"
sprintf() is like printf() but outputs to a string.
Also, as Parappa mentioned in the comments, you might want to use snprintf() to stop a buffer overflow from occuring (where the number you're converting doesn't fit the size of your string.) It works like this:
snprintf(str, sizeof(str), "%d", num);
Behind the scenes, lexical_cast does this:
std::stringstream str;
str << myint;
std::string result;
str >> result;
If you don't want to "drag in" boost for this, then using the above is a good solution.
We can define our own iota function in c++ as:
string itoa(int a)
{
string ss=""; //create empty string
while(a)
{
int x=a%10;
a/=10;
char i='0';
i=i+x;
ss=i+ss; //append new character at the front of the string!
}
return ss;
}
Don't forget to #include <string>.
ะก++11 finally resolves this providing std::to_string.
Also boost::lexical_cast is handy tool for older compilers.
I use these templates
template <typename T> string toStr(T tmp)
{
ostringstream out;
out << tmp;
return out.str();
}
template <typename T> T strTo(string tmp)
{
T output;
istringstream in(tmp);
in >> output;
return output;
}
Try Boost.Format or FastFormat, both high-quality C++ libraries:
int i = 10;
std::string result;
WIth Boost.Format
result = str(boost::format("%1%", i));
or FastFormat
fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);
Obviously they both do a lot more than a simple conversion of a single integer
You can actually convert anything to a string with one cleverly written template function. This code example uses a loop to create subdirectories in a Win-32 system. The string concatenation operator, operator+, is used to concatenate a root with a suffix to generate directory names. The suffix is created by converting the loop control variable, i, to a C++ string, using the template function, and concatenating that with another string.
//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>
using namespace std;
string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an */
/* integer as input and as output, */
/* returns a C++ string. */
/* itoa() returned a C-string (null- */
/* terminated) */
/* This function is not needed because*/
/* the following template function */
/* does it all */
/**************************************/
string r;
stringstream s;
s << x;
r = s.str();
return r;
}
template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of */
/* C++ templates. This function will */
/* convert anything to a string! */
/* Precondition: */
/* operator<< is defined for type T */
/**************************************/
string r;
stringstream s;
s << argument;
r = s.str();
return r;
}
int main( )
{
string s;
cout << "What directory would you like me to make?";
cin >> s;
try
{
mkdir(s.c_str());
}
catch (exception& e)
{
cerr << e.what( ) << endl;
}
chdir(s.c_str());
//Using a loop and string concatenation to make several sub-directories
for(int i = 0; i < 10; i++)
{
s = "Dir_";
s = s + toString(i);
mkdir(s.c_str());
}
system("PAUSE");
return EXIT_SUCCESS;
}
Allocate a string of sufficient length, then use snprintf.
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
I wrote this thread-safe function some time ago, and am very happy with the results and feel the algorithm is lightweight and lean, with performance that is about 3X the standard MSVC _itoa() function.
Here's the link. Optimal Base-10 only itoa() function? Performance is at least 10X that of sprintf(). The benchmark is also the function's QA test, as follows.
start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
if (i != atoi(_i32toa(buff, (int32_t)i))) {
printf("\nError for %i", i);
}
if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));
There are some silly suggestions made about using the caller's storage that would leave the result floating somewhere in a buffer in the caller's address space. Ignore them. The code I listed works perfectly, as the benchmark/QA code demonstrates.
I believe this code is lean enough to use in an embedded environment. YMMV, of course.
The best answer, IMO, is the function provided here:
http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
It mimics the non-ANSI function provided by many libs.
char* itoa(int value, char* result, int base);
It's also lightning fast and optimizes well under -O3, and the reason you're not using c++ string_format() ... or sprintf is that they are too slow, right?
If you are interested in fast as well as safe integer to string conversion method and not limited to the standard library, I can recommend the format_int method from the {fmt} library:
fmt::format_int(42).str(); // convert to std::string
fmt::format_int(42).c_str(); // convert and get as a C string
// (mind the lifetime, same as std::string::c_str())
According to the integer to string conversion benchmarks from Boost Karma, this method several times faster than glibc's sprintf or std::stringstream. It is even faster than Boost Karma's own int_generator as was confirm by an independent benchmark.
Disclaimer: I'm the author of this library.
Note that all of the stringstream methods may involve locking around the use of the locale object for formatting. This may be something to be wary of if you're using this conversion from multiple threads...
See here for more. Convert a number to a string with specified length in C++
On Windows CE derived platforms, there are no iostreams by default. The way to go there is preferaby with the _itoa<> family, usually _itow<> (since most string stuff are Unicode there anyway).
Most of the above suggestions technically aren't C++, they're C solutions.
Look into the use of std::stringstream.