tags:

views:

824

answers:

8
+1  Q: 

C++ and C file I/O

C++ file i/o is tougher than c file i/o. So in c++, creating a new library for file i/o is useful or not? I mean Can anyone pls tell are there any benefits in c++ file i/o ?

+1  A: 

Lots. Drawbacks too. See C++ language FAQ for details. In short: type-safety and user-defined types.

EFraim
Illusionary type safety to be precise.
Anonymous
I don't quite understand the "Illusionary" term. It is quite real. Of course shooting yourself in a foot is always an option.
EFraim
Illusionary? Explain.
jalf
because of the way that things can be autocasted through temporaries things can jump type.
David Allan Finch
@David: Things *can* jump type, but nothing in the standard libraries does this, and common wisdom is to limit user-defined conversions to a minimum to avoid this.
j_random_hacker
@David: OTOH I consider it a bug that the seemingly reasonable code 'std::ofstream("somefile") << "abc");' outputs "0" to somefile on most implementations, due to deep C++ weirdnesses (specifically, some operator<<() overloads are members of iostream while others are free functions).
j_random_hacker
+2  A: 

std::ifstream and std::ofstream are already in stl library. You don't have to create your own.

The main benefit is all outputs and inputs are type safety.

Mykola Golubyev
+2  A: 

C and C++ are two different languages. C++ file io takes some time getting used to, but once you are using algorithms, exceptions etc they tend to fall into place very naturally.

dirkgently
+9  A: 

Opinion

I don't know of any real project that uses C++ streams. They are too slow and difficult to use. There are several newer libraries like FastFormat and the Boost version that claim to be better there was a piece in the last ACCU Overload magazine about them. Personally I have used the c FILE library for the last 15 years or so in C++ and I can see no reason yet to change.

Speed

Here is small test program (I knock together quickly) to show the basic speed problem:

#include <stdio.h>
#include <time.h>

#include<iostream>
#include<fstream>

using namespace std;

int main( int argc, const char* argv[] )
    {
    const int max = 1000000;
    const char* teststr = "example";

    int start = time(0);
    FILE* file = fopen( "example1", "w" );
    for( int i = 0; i < max; i++ )
        {
        fprintf( file, "%s:%d\n", teststr, i );
        }
    fclose( file );
    int end = time(0);

    printf( "C FILE: %ds\n", end-start );

    start = time(0);
    ofstream outdata;
    outdata.open("example2.dat");
    for( int i = 0; i < max; i++ )
        {
        outdata << teststr << ":" << i << endl;
        }
    outdata.close();
    end = time(0);

    printf( "C++ Streams: %ds\n", end-start );

    return 0;
    }

And the results on my PC:

C FILE: 5s
C++ Streams: 260s

Process returned 0 (0x0)   execution time : 265.282 s
Press any key to continue.

As we can see just this simple example is 52x slower. I hope that there are ways to make it faster!

NOTE: changing endl to '\n' in my example improved C++ streams making it only 3x slower than the FILE* streams (thanks jalf) there may be ways to make it faster.

Difficulty to use

I can't argue that printf() is not terse but it is more flexible (IMO) and simpler to understand, once you get past the initial WTF for the macro codes.

double pi = 3.14285714;

cout << "pi = " << setprecision(5)  << pi << '\n';
printf( "%.5f\n", pi );

cout << "pi = " << fixed << showpos << setprecision(3) << pi << '\n'; 
printf( "%+.3f\n", pi );

cout << "pi = " << scientific << noshowpos << pi<< '\n';
printf( "%e\n", pi );

The Question

Yes, may be there is need of a better C++ library, many be FastFormat is that library, only time will tell.

dave

David Allan Finch
-1 "difficult to use" without justification
Maybe he was referring to iomanip formatting? Issues with atomicity/multithreading? Illusionary type safety? And moderate performance?
Anonymous
If you have an opinion of why they are not difficult to use how about posting an answer!
David Allan Finch
I have used C++ since the days of CFront may be my opinion might be worth thinking about. I agree with the /Illusionary type safety/ of Unknowns comment. I would say that 90% of my output code just prints strings and numbers.
David Allan Finch
I was a cfront user too. It doesn't make my opinions particularly valid.
anon
@David: I've seen numerous references to slowness of iostreams around the web, though I've never bothered with my own tests. OTOH, I find that writing an operator<<() for your own classes is a nice way to work, especially when debugging. OT3H, managing state with iostreams is a pain.
j_random_hacker
You can still use << with FILE* if you want to write it that way :)
David Allan Finch
I agree that having used C Front is a bit of a bogus point ;) May be my test will prove that it slower. FastFormat claims to over come these problems.
David Allan Finch
your comparison is flawed. The C and C++ versions don't do the same thing. The c++ version flushes the buffer after every line (endl). Sometimes, reading the documentation on the code you use is a good idea.
jalf
Calling printf more flexible is nonsense too. It doesn't work with user-defined types. That's hardly flexible. It is far *less* flexible than iostreams. And i'd argue that the C++ version is a lot easier to understand. I can guess what setprecision does. %+.3 is less obvious.
jalf
Good point - it has been such a long time since I used C++ streams. i change it to << '\n' and the time changed to 15s so that it is still 3x slower.
David Allan Finch
Yes %.3 is not obvious to those that are not in to the idiom of printf but how do you create 0 padded 5 width number in C++ streams?
David Allan Finch
Also I though C++ streams was simpler ;) how come endl is slower than '\n' anyway!
David Allan Finch
I think this illustrates the unsuitability of SO for discussion. Perhaps this should be taken to somewhere like comp.lang.c++.moderated?
anon
std::endl is slower than simply inserting a line feed because std::endl is defined to flush the stream at the same time.
Jon Trauntvein
When you change the C FILE to fflush after every write the times are the same. So the Buffered writes in C++ Streams are three times slower but the unbuffered are the same. This is probably because the C++ streams buffer is not implemented well.
David Allan Finch
Buffer overflows anyone?
Edouard A.
@David: std::cout << std::setfill('0') << setw(5) << 1; outputs 00001. Was that what you wanted? As far as I know, everything printf can do, iostreams can do as well. And tbh, I think the syntax for both is awful. :p
jalf
cout << setfill('0') << setw(5) << 1; vs printf( "%05d", 1 );
David Allan Finch
BTW setfill('0') << setw(5) seems way more self-explaining than %05.
EFraim
+5  A: 

Banishing buffer overruns seems like a big win for C++ to me.

anon
And what about the extra cost of the dynamic storage. Have you attually compaired the costs of using it. See: /FastFormat in the last ACCU's Overload/.
David Allan Finch
I presume you're talking about gets(). Are there any other standard C I/O functions that could overrun a buffer?
j_random_hacker
Sure, scanf (or fscanf), if you're not careful.
Mikeage
@Mikeage: Good point, %s in ...scanf() is a buffer overrun waiting to happen.
j_random_hacker
+6  A: 

Please have a look at

http://www.ddj.com/cpp/184403651

then You will prefer C++ I/O than C I/O.

in short C is prefered if you know data size prior to read or write and for speed. C++ is prefered if you don't know data size and for efficient code.

lakshmanaraj
ok thanks for your answer. i will look into that webpage
Chaithra
+1  A: 
Jon Trauntvein
+1  A: 

In response to David Allan Finch's answer, I fixed an error in his benchmarking code (he flushed the stream in the C++ version after every single line), and reran the test:

The C++ loop now looks like this:

start = time(0);
{
 ofstream outdata("example2.txt");
 for( int i = 0; i < max; i++ )
 {
  outdata << teststr << ":" << i << "\n"; // note, \n instead of endl
 }
}
end = time(0);

I run 10000000 iterations (10 times more than in the original code, because otherwise, the numbers are just too small for time()'s lousy resolution to give us anything meaningful)) And the output is:

G++ 4.1.2:
C FILE: 4s
C++ Streams: 6s

MSVC9.0:
C FILE: 10s
C++ Streams: 23s

(note, the MSVC version was run on my laptop with a significantly slower harddrive)

But this gives us a performance difference of 1.5-2.3x, depending on the implementation. and other external factors.

jalf
The same code on my UltraSparc I get 9s vs 21s and using /tmp I get 5s vs 16s. Oh and I did edit my answer ;)
David Allan Finch