28

Googling file input I found two ways to input text from a file - fopen and ifstream. Below are the two snippets. I have a text file consisting of one line with an integer I need to read in. Should I use fopen or ifstream?

SNIPPET 1 - FOPEN

FILE * pFile = fopen ("myfile.txt" , "r");
char mystring [100];
if (pFile == NULL) 
{
    perror ("Error opening file");
}
else 
{
    fgets (mystring , 100 , pFile);
    puts (mystring);
    fclose (pFile);
}

SNIPPET 2 - IFSTREAM

string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
    while ( myfile.good() )
    {
        getline (myfile,line);
        cout << line << endl;
    }
    myfile.close();
}
else 
{  
    cout << "Unable to open file"; 
}
almightyGOSU
  • 3,731
  • 6
  • 31
  • 41

2 Answers2

41

Since this is tagged as C++, I will say ifstream. If it was tagged as C, i'd go with fopen :P

Vinicius Kamakura
  • 7,665
  • 1
  • 29
  • 43
21

I would prefer ifstream because it is a bit more modular than fopen. Suppose you want the code that reads from the stream to also read from a string stream, or from any other istream. You could write it like this:

void file_reader()
{ 
    string line;
    ifstream myfile ("example.txt");
    if (myfile.is_open())
    {
        while (myfile.good())
        {
          stream_reader(myfile);
        }
        myfile.close();
    }
    else 
    {  
        cout << "Unable to open file"; 
    }
}

void stream_reader(istream& stream)
{
    getline (stream,line);
    cout << line << endl;
}

Now you can test stream_reader without using a real file, or use it to read from other input types. This is much more difficult with fopen.

Josh Peterson
  • 2,299
  • 19
  • 21
  • Why wouldn't `void stream_reader(FILE *stream) { fgets(line, len, stream); puts(line); }` be essentially identical? – Jerry Coffin Jun 19 '11 at 15:07
  • Is it possible to create a `FILE*` without a call to fopen or tmpfile? I don't believe it is, but I may be wrong. Since the operation of `stream_reader` only requires a stream, not a file, I would rather not overconstrain it by having it require a `FILE*`. In unit tests it might be easier to pass it a string stream instead of a `FILE*`, for example. – Josh Peterson Jun 20 '11 at 01:39
  • Yes, from that perspective, the C version is more tightly constrained -- there's no provision for `FILE *` that refers to a string rather than a file, at least in the standard (though some libraries have provided/used that, at least internally, for quite some time). If you *really* need to avoid that, you can pass in a pointer to a function to do the writing, but it's definitely clumsier. – Jerry Coffin Jun 20 '11 at 03:36
  • Definitely a +1 for this response - I use ostream in my code for the same modularity - being able to decide if I want to output data to a file, the terminal, etc. – Vee Nov 21 '18 at 17:02