tags:

views:

964

answers:

3

I've read a lot of tutorials and can not really find anything comprehensive on this subject.

I had written the following code to do one function:

#include <fstream>
#include <string>
#include <iostream>

using namespace std;

ifstream ReadFile( ifstream& openInputFile, string& sLine, int& chgLine );


int main()
{
    int chgLine;
    string MyFile, sLine, 
    sFile = "test.txt";

    cout << "Enter a file: ";
    cin >> MyFile ;

    ifstream openInputFile;


    if ( MyFile != sFile )    // file must be 'hello.cpp' to proceed
    {
       cout << "Error";
       exit(0);
    }
                         // if correct file is entered print the contents of it

        ReadFile( openInputFile, sLine, chgLine );

    system("pause");
    return 0;
}

ifstream ReadFile( ifstream& openInputFile, string& sLine, int& chgLine )
{ 

       while ( getline ( openInputFile, sLine ) )
       {
      if ( sLine.length() == 0 ) continue;  // to proceed

             for ( chgLine = 0; chgLine < sLine.length(); chgLine++ )
           {
                if ( sLine[chgLine] >= 97 && sLine[chgLine] <= 122 || sLine[chgLine] >= 65 && sLine[chgLine] <= 90  )
                {
                     cout << sLine[chgLine];
                }

             }
        }
}

But now I've decided to break all of this up into three functions that do what I want separately, and then call them from the main() function.

The first function opens the file:

#include <iostream>
#include <fstream>
using namespace std;

ifstream openInputFile()

{
       // use a pointer..return a pointer
       // ifstream definition is the challenge
  ifstream *fp;
  //fp = new ifstream openInputFile;
  return openInputFile;

}

int main()

{
    cout << "Hello, world!" << endl;

    system("pause");
    return 0;
}

I get stuck trying to return a pointer. I don't understand what I'm doing wrong. How can I get the last bit of code to work? And how does one return a pointer with ifstream if it has the function's type?

A: 

It seems you shouldn't need to return by pointer in the above case.

If you do need to return a modified result, you may want to look into return value optimization(RVO). With RVO, you save yourself copying of temporaries (and in your case dynamic allocation) by passing in the output parameter by reference.

For example

void openInputFile(ifstream& file)
{
    file.open(...);
}

int main()
{
    ifstream file;
    openInputFile(file);

    // Work with file, since file is
    // on the stack you don't have to worry about cleanup/etc
}

This gets rid of a lot of the problems dealing with dynamic allocation and may avoid the problems you are coming across. You seem to be kind-of onto this, so I'm puzzled as to the need to return the ifstream.

If you need do need to return by pointer, in that case in seems all your missing is an asterisk. For example this function:

    ifstream* Blah();

should work.

Doug T.
+1  A: 

The C++ way to do this would be to create a class that wraps up all of the opening, reading and writing. Note that this would also handle closing the file automatically, a good example of RAII.

// FancyFile.h:

class FancyFile
{
    private:
        std::ifstream stream;

    public:
        void DoMagic();

        InputFile(const std::string FilePath)
            { stream.open(FilePath.c_str()); }
        ~InputFile(void)
            { stream.close(); }
};
// FancyFile.cpp:

#include <fstream>
#include <string>

#include "FancyFile.h"

void FancyFile::DoMagic()
{
    //.. your custom file handling code goes here
}
// main:

#include "FancyFile.h"

int main()
{    
    FancyFile myFancyFile("test.txt");

    myFancyFile.DoMagic();

    system("pause");
    return 0;
}
e.James
A: 

The example doesn't actually show you opening the ifstream with the file name specified?
The example is requesting user input of the file name, and then saying it can only be one value?

As Doug T. said, it would probably be nicer from the example code to make use of scope to manage the ifstream.
Anyway, here is an example returning a pointer

ifstream * openInputFile( ) {
  string MyFil;
  string sFile = "test.txt";

  cout << "Enter a file: ";
  cin >> MyFile ;

  if ( MyFile == sFile )   
  {
    ifstream * inputFile = new ifstream( MyFile.c_str() );
    // do some other stuff here?
    return inputFile;
  } else {
    return null;
  }
}

Then main can be

int main()
{
  int chgLine;
  string sLine;
  ifstream *inputFile = openInputFile();
  if( NULL == inputFile )
  {
    cout << "Error";
    exit(0);
  }
...
Greg Domjan