1

I'm a C++ beginner and having just finished C++ Primer, I'm playing around with a few projects of my own. One thing I'm noticing as I do this is that while C++ Primer tended to emphasize std::fstream as the way to go for file IO, many programs instead use FILE*.

Is there any reason for this? If there is, in what situations would/should you use fstream over FILE or is there a 3rd option unknown to me that you would recommend?

Thanks!

daniel gratzer
  • 52,833
  • 11
  • 94
  • 134
  • 1
    `FILE` is a C thing. `std::fstream` is a C++ thing. One is more suited to C, whilst the other can only be used in C++. – Flexo May 13 '12 at 21:42
  • So is it a bad idea to be using FILE at all? I've just seen it in others code is all – daniel gratzer May 13 '12 at 21:43
  • I live by the guideline: *"prefer the C++ way"* - it makes life so much simpler. Some people (teachers/books) cling on to old C habits for no discernible reason or fail to appreciate the differences between C and C++ and what it means for their programming. I'd take heavy usage of `FILE*` as a hint to avoid that book/tutorial/class. – Flexo May 13 '12 at 21:44
  • 1
    `fstream` is a bit notoriously inefficient compared to `fread`. – chris May 13 '12 at 21:45
  • 2
    @chris [citation needed] – Flexo May 13 '12 at 21:46
  • In a performance critical application (high-speed logging?) you might like to profile the various IO methods and compare. For C `FILE*`, you can use C++ to create a wrapper like [in this example](http://codereview.stackexchange.com/q/4679). – Kerrek SB May 13 '12 at 21:46
  • http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.1 – Flexo May 13 '12 at 21:49
  • 1
    @chris If you're talking about performance, maybe, but I guess you should profile it first to check if it's relevant for your application. Otherwise, prefer C++'s `iostream` unless you really need to sacrifice ease of use for performance. – Etienne de Martel May 13 '12 at 21:54
  • I'm going off of previous SO questions (which yes, I'll never find), where some higher rep people have stated that. Personally, I'd use `fstream` in a heartbeat, unless any performance boost from the alternative is significant to what I'm doing. – chris May 13 '12 at 22:05
  • 2
    Fact is that some implementations of file streams are pathetic. It is relatively hard but doable to implement streams with similar performance as stdio functions, however (and I'd think with better performance, actually, but I don't have an implementation with this property). On thing to note is that many applications actively slow down their output performance using `std::endl`: I found this at the heart of performance problems with IOstreams more than once in production code. Also, on some systems you might want to use `std::sync_with_stdio(false)` to release the hand-brake on IOstreams. – Dietmar Kühl May 13 '12 at 22:18
  • The only thing I've found so far on here with numbers is: http://stackoverflow.com/a/2873251/168175 which seems to say "not much in it". – Flexo May 13 '12 at 22:34

1 Answers1

2

The only reason to use stdio (i.e. the FILE* family of functions) in C++ is to interface with C code taking FILE* parameters. Many people who learned C and/or C++ using stdio believe these functions are somehow superior. The main complaint is that format specifiers using stdio are so much shorter. Unfortunately, they are also error-prone and despite warnings pointing out inconsistencies between format specifiers and actual arguments I have yet to see a program which uses stdio non-trivial and correctly.

The one omission in IOstreams which stdio does better is that the scanf() functions can do some interesting parsing. This can be added to IOstreams quite easily but it isn't part of the standard library (and it isn't as terse as the format specifiers).

Personally, I consider the drawbacks irrelevant compared to the advantages:

  • type-safe reading and writing
  • user-defined support for user-defined types
  • support for user-defined sources and destinations
  • to a lesser degree control over formatting of numerical types

Due to a series of articles and some extremely bad implementations of early IOstreams (some of which still seem to linger in popular platforms) the C++ streams have gained an incorrect reputation of being slow. Yes, it is possibe to make sure that they are a lot slower than stdio but is definitely possible to implement them with similar performance as stdio. There are a few easy performance mistakes the user needs to avoid, however:

  1. Do not use std::endl. Period. If you really mean to write a newline followed by a flush say so: out << '\n' << std::flush. This is what std::endl does but std::endl is incorrectly used in the vaste majority of the cases with the unintended flush causing major performance problems.
  2. Make sure the library doesn't waste time keeping things in sync with stdio operations: call std::sync_with_stdio(false); unless you are mixing output to the standard stream object (std::cin, etc. and stdin, etc.). Although the effect is only required for the standard stream objects, there are bad implementations of IOstreams where this also affects file streams.
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380