As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
In new C++ code, I tend to use the C++ iostream library instead of the C stdio library.
I've noticed some programmers seem to stick to stdio, insisting that it's more portable.
Is this really the case? What is better to use?
To answer the original question:
Anything that can be done using stdio can be done using the iostream library.
Disadvantages of iostreams: verbose
Advantages of iostreams: easy to extend for new non POD types.
The step forward the C++ made over C was type safety.
iostreams was designed to be explicitly type safe. Thus assignment to an object explicitly checked the type (at compiler time) of the object being assigned too (generating an compile time error if required). Thus prevent run-time memory over-runs or writing a float value to a char object etc.
scanf()/printf() and family on the other hand rely on the programmer getting the format string correct and there was no type checking (I believe gcc has an extension that helps). As a result it was the source of many bugs (as programmers are less perfect in their analysis than compilers [not going to say compilers are perfect just better than humans]).
Just to clarify comments from Colin Jensen.
The iostream libraries have been stable since the release of the last standard (I forget the actual year but about 10 years ago).
To clarify comments by Mikael Jansson.
The other languages that he mentions that use the format style have explicit safeguards to prevent the dangerous side effects of the C stdio library that can (in C but not the mentioned languages) cause a run-time crash.
N.B. I agree that the iostream library is a bit on the verbose side. But I am willing to put up with the verboseness to ensure runtime safety. But we can mitigate the verbosity by using Boost Format Library.
#include <iostream>
#include <iomanip>
#include <boost/format.hpp>
struct X
{ // this structure reverse engineered from
// example provided by 'Mikael Jansson' in order to make this a running example
char* name;
double mean;
int sample_count;
};
int main()
{
X stats[] = {{"Plop",5.6,2}};
// nonsense output, just to exemplify
// stdio version
fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
stats, stats->name, stats->mean, stats->sample_count);
// iostream
std::cerr << "at " << (void*)stats << "/" << stats->name
<< ": mean value " << std::fixed << std::setprecision(3) << stats->mean
<< " of " << std::setw(4) << std::setfill(' ') << stats->sample_count
<< " samples\n";
// iostream with boost::format
std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n")
% stats % stats->name % stats->mean % stats->sample_count;
}
It's just too verbose.
Ponder the iostream construct for doing the following (similarly for scanf):
// nonsense output, just to examplify
fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
stats, stats->name, stats->mean, stats->sample_count);
That would requires something like:
std::cerr << "at " << static_cast<void*>(stats) << "/" << stats->name
<< ": mean value " << std::precision(3) << stats->mean
<< " of " << std::width(4) << std::fill(' ') << stats->sample_count
<< " samples " << std::endl;
String formatting is a case where object-orientedness can, and should be, sidestepped in favour of a formatting DSL embedded in strings. Consider Lisp's format, Python's printf-style formatting, or PHP, Bash, Perl, Ruby and their string intrapolation.
iostream for that use case is misguided, at best.
The Boost Format Library provides a type-safe, object-oriented alternative for printf-style string formatting and is a complement to iostreams that does not suffer from the usual verbosity issues due to the clever use of operator%. I recommend considering it over using plain C printf if you dislike formatting with iostream's operator<<.
Back in the bad old days, the C++ Standards committee kept mucking about with the language and iostreams was a moving target. If you used iostreams, you were then given the opportunity to rewrite parts of your code every year or so. Because of this, I always used stdio which hasn't changed significantly since 1989.
If I were doing stuff today, I would use iostreams.
If, like me, you learned C before learning C++, the stdio libraries seem more natural to use. There are pros and cons for iostream vs. stdio but I do miss printf() when using iostream.
In principle I would use iostreams, in practice I do too much formatted decimals, etc that make iostreams too unreadable, so I use stdio. Boost::format is an improvement, but not quite motivating enough for me. In practice, stdio is nearly typesafe since most modern compilers do argument checking anyway.
It's an area where I'm still not totally happy with any of the solutions.
I'll be comparing the two mainstream libraries from the C++ standard library.
You shouldn't use C-style-format-string-based string-processing-routines in C++.
Several reasons exist to mit their use:
Not typesafe
You can't pass non-POD types to variadic argument lists (i.e., neither to scanf+co., nor to printf+co.),
or you enter the Dark Stronghold of Undefined Behaviour
Easy to get wrong:
You must manage to keep the format string and the "value-argument-list" in sync
You must keep in sync correctly
Subtle bugs introduced at remote places
It is not only the printf in itself that is not good. Software gets old and is refactored and modified, and errors might be introduced from remote places. Suppose you have
.
// foo.h
...
float foo;
...
and somewhere ...
// bar/frob/42/icetea.cpp
...
scanf ("%f", &foo);
...
And three years later you find that foo should be of some custom type ...
// foo.h
...
FixedPoint foo;
...
but somewhere ...
// bar/frob/42/icetea.cpp
...
scanf ("%f", &foo);
...
... then your old printf/scanf will still compile, except that you now get random segfaults and you don't remember why.
Verbosity of iostreams
If you think printf() is less verbose, then there's a certain probability that you don't use their iostream's full force. Example:
printf ("My Matrix: %f %f %f %f\n"
" %f %f %f %f\n"
" %f %f %f %f\n"
" %f %f %f %f\n",
mat(0,0), mat(0,1), mat(0,2), mat(0,3),
mat(1,0), mat(1,1), mat(1,2), mat(1,3),
mat(2,0), mat(2,1), mat(2,2), mat(2,3),
mat(3,0), mat(3,1), mat(3,2), mat(3,3));
Compare that to using iostreams right:
cout << mat << '\n';
You have to define a proper overload for operator<< which has roughly the structure of the printf-thingy, but the significant difference is that you now have something re-usable and typesafe; of course you can also make something re-usable for printf-likes, but then you have printf again (what if you replace the matrix members with the new FixedPoint?), apart from other non-trivialities, e.g. you must pass FILE* handles around.
C-style format strings are not better for I18N than iostreams
Note that format-strings are often thought of being the rescue with internationalization, but they are not at all better than iostream in that respect:
printf ("Guten Morgen, Sie sind %f Meter groß und haben %d Kinder",
someFloat, someInt);
printf ("Good morning, you have %d children and your height is %f meters",
someFloat, someInt); // Note: Position changed.
// ^^ not the best example, but different languages have generally different
// order of "variables"
I.e., old style C format strings lack positional information as much as iostreams do.
You might want to consider boost::format, which offers support for stating the position in the format string explicitly. From their examples section:
cout << format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style.
Some printf-implementations provide positional arguments, but they are non-standard.
Should I never use C-style format strings?
Apart from performance (as pointed out by Jan Hudec), I don't see a reason. But keep in mind:
“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified” - Knuth
and
“Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you have proven that's where the bottleneck is.” - Pike
Yes, printf-implementations are usually faster than iostreams are usually faster than boost::format (from a small and specific benchmark I wrote, but it should largely depend on the situation in particular: if printf=100%, then iostream=160%, and boost::format=220%)
But do not blindly omit thinking about it: How much time do you really spend on text-processing? How long does your program run before exiting?
Is it relevant at all to fall back to C-style format strings, loose type safety, decrease refactorbility,
increase probability of very subtle bugs that may hide themselves for years and may only reveal themselves right
into your favourites customers face?
Personally, I wouldn't fall back if I can not gain more than 20% speedup. But because my applications
spend virtually all of their time on other tasks than string-processing, I never had to. Some parsers
I wrote spend virtually all their time on string processing, but their total runtime is so small
that it isn't worth the testing and verification effort.
Some riddles
Finally, I'd like to preset some riddles:
Find all errors, because the compiler won't (he can only suggest if he's nice):
shared_ptr<float> f(new float);
fscanf (stdout, "%u %s %f", f)
If nothing else, what's wrong with this one?
const char *output = "in total, the thing is 50%"
"feature complete";
printf (output);
For binary IO, I tend to use stdio's fread and fwrite. For formatted stuff I'll usually use IO Stream although as Mikael said, non-trival (non-default?) formatting can be a PITA.
While there are a lot of benefits to the C++ iostreams API, one significant problem is has is around i18n. The problem is that the order of parameter substitutions can vary based on the culture. The classic example is something like:
// i18n UNSAFE
std::cout << "Dear " << name.given << ' ' << name.family << std::endl;
While that works for English, in Chinese the family name is comes first.
When it comes to translating your code for foreign markets, translating snippets is fraught with peril so new l10ns may require changes to the code and not just different strings.
boost::format seems to combine the best of stdio (a single format string that can use the parameters in a different order then they appear) and iostreams (type-safety, extensibility).
I use iostreams, mainly because that makes it easier to fiddle with the stream later on (if I need it). For example, you could find out that you want to display the output in some trace window -- this is relatively easy to do with cout and cerr. You can, off course, fiddle with pipes and stuff on unix, but that is not as portable.
I do love printf-like formatting, so I usually format a string first, and then send it to the buffer. With Qt, I often use QString::sprintf (although they recommend using QString::arg instead). I've looked at boost.format as well, but couldn't really get used to the syntax (too many %'s). I should really give it a look, though.
What I miss about the iolibraries is the formatted input.
iostreams does not have a nice way to replicate scanf() and even boost does not have the required extension for input.
stdio is better for reading binary files (like freading blocks into a vector<unsigned char> and using .resize() etc.). See the read_rest function in file.hh in http://nuwen.net/libnuwen.html for an example.
C++ streams can choke on lots of bytes when reading binary files causing a false eof.
Since iostreams have become a standard you should use them knowing that your code will work for sure with newer versions of compiler. I guess nowadays most of the compilers know very well about iostreams and there shouldn't be any problem using them.
But if you want to stick with *printf functions there can be no problem in my opinion.
Related
I switched to c++ because i heard its 400 times faster than python, But when i made an infinite loop that increments a variable and prints its value python seems to be faster, How can that be?
And how to optimize it?
Python script:
x = 1
while 1:
print(x)
x+=1
C++ code:
int x = 1;
while (1) {
cout << x << endl;
x++;
}
I tried optimizing it by putting this command:
ios_base::sync_with_stdio(false);
The speed became almost identical to python's but not faster.
Yeah and i did search for this topic i didn't find anything that explains why.
C++'s std::endl flushes the stream, python's print does not. Try using "\n", that should speed up the C++ code.
You are not benchmarking the language, you are benchmarking the OS.
The time it takes to display text (by the windowing system) is longer than the time to prepare the characters (by your code) by orders of magnitude.
You will obtain the same behavior with any language.
C++'s advantage in comparison with Python doesn't lie in operations constrained by the OS such as printing to the console, but rather:
The fact is it hard typed, thus minimizing run-time overhead due to dynamic typing and type safety
The fact C++ is compiled (and highly optimized) and Python is (mostly) interpreted
In it's memory management model (Python uses managed objects that require garbage collection)
C++ can give you more control when implementing performance critical code (as far as using assembly and taking advantage of specific hardware)
We have a bespoke datetime C++ class which represents time in number of seconds passed since epoch. This is stored as int64. This class provides number of helper functions to read and write various types of datetime formats.
Unfortunately it cant handle dates before epoch because its methods rely on gmtime() and mktime() for many operations, which on our windows system does not support dates before epoch. Does anyone knows of replacement of gmtime and mktime which support negative values on windows.
An example of this limitation is our applicatio's inability to store birthdays before 1970, that is because every date has to use this class.
I amy not be clear on what I am asking, this is because of my limited knowledge of datetime implementation/use and my reluctance to understand that huge legacy class, so if you feel this question can be framed in another way or I might look for something different feel free to suggest.
You could use Boost.DateTime, or use the Win32 APIs directly rather than the CRT.
It's likely that you have a lot of testing ahead of you to ensure that handling of data does not change in your rework. Make sure you have exhaustive unit tests in place for the library as it stands before you begin any refactoring.
If you have to consider your values being valid across multiple different locations in the world, use UTC time as your canonical form and translate to/from local time as needed for sensible input/display.
Maybe you've solved this problem already since it was years ago, but you could also use ICU. Examples at: http://userguide.icu-project.org/datetime/calendar/examples
Coming soon to a std::lib implementation near you:
#include <chrono>
#include <iostream>
int
main()
{
using namespace std::chrono;
std::cout << "Valid range is ["
<< sys_days{year::min()/January/1} + 0us << ", "
<< sys_days{year::max()/December/31} + 23h + 59min + 59s + 999'999us
<< "]\n";
}
Output:
Valid range is [-32767-01-01 00:00:00.000000, 32767-12-31 23:59:59.999999]
Preview available here.
Is there a way to use decimal data types such as decimal32, decimal64 or decimal128in my C++ programs?
The classes from the Decimal TR are not implemented for all compilers. Some compilers, e.g., gcc, implement the C Decimal TR and provide the corresponding extensions in C++, too. In the past there was an open source implementation for the C++ Decimal TR available but I failed to locate it. If your compiler doesn't support the decimal types, your best option is probably to create a wrapper for IBM's decNumber library.
To improve the situation in the future of C++, I have created a plan to update the TR and I'm going to turn the current TR into a complete proposal ready for the next C++ committee meeting (in April in Bristol), trying to get it adopted into the C++ standard, possibly into the revision planned for 2014. The implementation I have is part of my regular work and it isn't up to me to decide whether it is can be made available publically although there is some hope that it can be open sourced at some point.
You can use easy to use header-only solution for C++ with templates:
https://github.com/vpiotr/decimal_for_cpp
Notice that this is not a *Big*Decimal class; it is limited to 64 bits' worth of "mantissa" digits.
[taken from link]
#include "decimal.h"
using namespace dec;
// the following declares currency variable with 2 decimal points
// initialized with integer value (can be also floating-point)
decimal<2> value(143125);
// to use non-decimal constants you need to convert them to decimal
value = value / decimal_cast<2>(333.0);
// output values
cout << "Result is: " << value << endl;
// this should display something like "429.80"
// to mix decimals with different precision use decimal_cast
decimal<6> exchangeRate(12.1234);
value = decimal_cast<2>(decimal_cast<6>(value) * exchangeRate);
cout << "Result 2 is: " << value << endl;
// this should display something like "5210.64"
cout << "Result 2<6> is: " << decimal_cast<6>(value) << endl;
// this should display something like "5210.640000"
use an int32 or int64, and (manually) shift the decimal point to where you want it to be. If you're measuring dollars, for example, just measure cents instead and display the value differently. simple!
Boost has cpp_dec_float as well. That's probably the best solution until it's adopted into the standard.
https://www.boost.org/doc/libs/1_68_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html
EDIT: This library uses floating point values in the implementation so is not a true decimal math library IMO.
gcc/clang (usually) come with their own floating point decimal implementations, if your distro decides to compile them into whatever gcc/clang version they offer (not the case for some arm distros I tried out). This is why you sometimes need a custom decimal type implementation. Try mine for ideas (tested on i586 all the way to aarch64).
decimal.h this library is not exit is is saying by my compiler.
/tmp/TQDyfEvEXQ.cpp:2:10: fatal error: decimal.h: No such file or directory
2 | #include <decimal.h>
| ^~~~~~~~~~~
compilation terminated.```
Does C++ stl have a standard time class? Or do I have to convert to c-string before writing to a stream. Example, I want to output the current date/time to a string stream:
time_t tm();
ostringstream sout;
sout << tm << ends;
In this case I get the current date/time written out as a number without any formatting. I can use
c- runtime function strftime to format tm first, but that seems like it should not be necessary if the stl has a time class that can be instantiated from time_t value
Not part of STL but well known library is boost.
I would go the way of using boost::date. Here are some examples: http://www.boost.org/doc/libs/1_55_0/doc/html/date_time/date_time_io.html#date_time.io_tutorial.
If you did not try out boost yet I encourage you to do so as it saves you from a lot of nasty issues, as it masks most OS dependent things like threading for example. Many things in boost are header only (template libraries). However datetime requires a lib or dll.
EDIT
The standard "datetime" class is std::chrono::time_point since C++11. The code in the question should be roughly equivalent to
const auto now = std::chrono::system_clock::now();
const auto t_c = std::chrono::system_clock::to_time_t(now);
std::cout << std::put_time(std::localtime(&t_c), "%F %T.\n");
OLD ANSWER
Nitpicking: The STL being the Standard Template Library deals with generic container and algorithms etc. and is unlikely to incorporate classes for date handling and calculation even in the future…
The C++ Standard Library itself includes the STL and a previous version of the C standard library. The latter offers some date and time related functions via #include <ctime> which has already been mentioned above.
If wrapping (or simply using) these functions is sufficient (and quicker) than pulling in boost, go with these. There is nothing wrong with them.
C++ now has the chrono libraries for date and time.
This is documented on http://en.cppreference.com/w/cpp/chrono and http://www.cplusplus.com/reference/chrono/
There are get_time and put_time in <iomanip> header (i guess these came with C++11) which effectively does string formatting or parsing jobs.
There is also a ctime(&time_t) method which outputs string (char*).
OK. Here is closest I have found about directly writing time to a stream:
time_t t(time(NULL)); // current time
tm tm(*localtime(&t));
std::locale loc(""); // current user locale
ostringstream sout;
const std::time_put<TCHAR> &tput =
std::use_facet<std::time_put<TCHAR> >(loc);
tput.put(sout.rdbuf(), sout, _T('\0'), &tm, _T('x'));
sout << ends;
CString sTest(sout.str().c_str());
A very helpful guide is the Apache C++ Standard Library Reference Guide
http://stdcxx.apache.org/doc/stdlibref/time-put.html#sec13
Well, it's been a dozen years since this question was asked. And now (in C++20) it finally has a better answer.
Yes, there are several standard date/time classes in C++20 (not just one). Each serves different purposes in a strongly typed system. For example std::chrono::zoned_time represents a pairing of a std::chrono::time_zone and a std::chrono::time_point<system_clock, SomeDuration>, and represents the local time in some geographic area. Here is how you might create and print the local time in your current time zone to the finest sub-second precision your OS allows.
cout << zoned_time{current_zone(), system_clock::now()} << '\n';
If you need the local time somewhere else, that is just as easily obtained:
cout << zoned_time{"Africa/Casablanca", system_clock::now()} << '\n';
Unlike in previous C++ standards, time_points based on system_clock are now guaranteed to represent UTC, neglecting leap seconds (aka Unix Time). So to get the current time in UTC it is simply:
cout << system_clock::now() << '\n';
Though if you really wanted to use a zoned_time instead (for example the code may be generic), this also works:
cout << zoned_time{"UTC", system_clock::now()} << '\n';
See https://en.cppreference.com/w/cpp/chrono for many more standard date/time classes. All of them are thread-safe. And you are no longer limited to seconds precision.
I read somewhere that snprintf is faster than ostringstream. Has anyone has any experiences with it? If yes why is it faster.
std::ostringstream is not required to be slower, but it is generally slower when implemented. FastFormat's website has some benchmarks.
The Standard library design for streams supports much more than snprintf does. The design is meant to be extensible, and includes protected virtual methods that are called by the publicly exposed methods. This allows you to derive from one of the stream classes, with the assurance that if you overload the protected method you will get the behavior you want. I believe that a compiler could avoid the overhead of the virtual function call, but I'm not aware of any compilers that do.
Additionally, stream operations often use growable buffers internally; which implies relatively slow memory allocations.
We replaced some stringstreams in inner loops with sprintf (using statically allocated buffers), and this made a big difference, both in msvc and gcc. I imagine that the dynamic memory management of this code:
{
char buf[100];
int i = 100;
sprintf(buf, "%d", i);
// do something with buf
}
is much simpler than
{
std::stringstream ss;
int i = 100;
ss << i;
std::string s = ss.str();
// do something with s
}
but i am very happy with the overall performance of stringstreams.
Some guys would possibly tell you about that the functions can't be faster than each other, but their implementation can. That's right i think i would agree.
You are unlikely to ever notice a difference in other than benchmarks. The reason that c++ streams generally tend to be slower is that they are much more flexible. Flexibility most often comes at the cost of either time or code growth.
In this case, C++ streams are based on stream-buffers. In itself, streams are just the hull that keep formatting and error flags in place, and call the right i/o facets of the c++ standard library (for example, num_put to print numbers), that print the values, well formatted, into the underlying stream-buffer connected to the c++ stream.
All this mechanisms - the facets, and the buffers, are implemented by virtual functions. While there is indeed no mark note, those functions must be implemented to be slower than c stdio pendants that fact will make them somewhat slower than using c stdio functions normally (i benchmark'ed that some time ago with gcc/libstdc++ and in fact noticed a slowdown - but which you hardly notice in day-by-day usage).
Absolutely this is implementation-specific.
But if you really want to know, write two small programs, and compare them. You would need to include typical usage for what you have in mind, the two programs would need to generate the same string, and you would use a profiler to look at the timing information.
Then you would know.
One issue would probably be that the type safety added by ostringstream carries extra overhead. I've not done any measurements, though.
As litb said, standard streams support many things we don't always need.
Some streams implementation get rid of this never used flexibility, see FAStream for instance.
It's quite possible that because sprintf is part of the CRT that is written in assembly. The ostringstream is part of the STL, and probably a little more generically written, and has OOP code/overhead to deal with.
Yes, if you run the function below on a few million numbers with Visual C++ 5.0, the first version takes about twice as long as the second and produces the same output.
Compiling tight loops into a .exe and running the Windows timethis something.exe' or the Linuxtime something' is how I investigate most of my performance curiosities. (`timethis' is available on the web somewhere)
void Hex32Bit(unsigned int n, string &result)
{
#if 0
stringstream ss;
ss
<< hex
<< setfill('0')
<< "0x" << setw(8) << n
;
result = ss.str();
#else
const size_t len = 11;
char temp[len];
_snprintf(temp, len, "0x%08x", n);
temp[len - 1] = '\0';
result = temp;
#endif
}
One reason I know that the printf family of functions are faster than the corresponding C++ functions (cout, cin, and other streams) is that the latter do typechecking. As this usually involves some requests to overloaded operators, it can take some time.
In fact, in programming competitions it is often recommended that you use printf et al rather than cout/cin for precisely this reason.