Aaron
Aaron

Reputation: 3

Creating a public class in C++

I have a small problem if you do mind assisting please.

I am staring to learn how to work with classes but I have an issue when I trying make a certain part of a program (asking a user for filename to open) into a function and making it public.

In my original main.cpp file, I have this code where I try to ask a user for the file name in which he or she wants to open:

    char in_filename[50];
    ifstream infile;
    cin.getline(in_filename, 50);
    infile.open(in_filename);

    if(!infile.is_open())
    {
        cout << "File cannot load."<< endl;
        exit(EXIT_FAILURE);
    }

int w, h;
string s;
infile >> s; 
outfile <<s<<endl;
infile >> w; 
outfile << w<<" ";
infile >> h; 
outfile <<h<<endl;
infile >> s; 
outfile <<s<<endl;

In my other .cpp called lib.cpp file where I have all my functions, I tried converting the code to this:

void PPMImage::GetFileName()
{
    char in_filename[50];
    ifstream infile;
    cin.getline(in_filename, 50);
    infile.open(in_filename);

    if(!infile.is_open())
    {
        cout << "File cannot load."<< endl;
        exit(EXIT_FAILURE);
    }

}

And in my header file, I have:

class Image
{
public:
void GetFileName();
};

After I create the class, my new main.cpp is:

Image bo;   //create object
bo.GetFileName();

int w, h;
string s;
infile >> s; 
outfile <<s<<endl;
infile >> w; 
outfile << w<<" ";
infile >> h; 
outfile <<h<<endl;
infile >> s; 
outfile <<s<<endl;

However, after I run the code, I get an error message saying 'infile' was not defined. Is this because infile is defined in lib.cpp and the the variable 'infile' in main.cpp is not picking it up, even though I called the function bo.GetFileName earlier? Is their an alternative to fixing? These are only exerts of my code. This is not all of it, but I feel this is the only code relevant to this problem. Any advice/assistance/suggestions is welcomed. Thank you for your support!

Upvotes: 0

Views: 137

Answers (3)

charlie
charlie

Reputation: 309

infile was out of scope.There is one solution

change the value returned by the function GetFileName in lib.cpp

ifstream PPMImage::GetFileName()
{
    char in_filename[50];
    ifstream infile;
    cin.getline(in_filename,50);
    infile.open(in_filename);

    if(!infile.is_open())
    {
        cout<<"File cannot load"<<endl;
        exit(EXIT_FAILURE);
    }

    return infile;
}

Also,you should change the value type of GetFileName(),in your header file

Then fix main.cpp like this

Image bo;
ifstream infile=bo.GetFileName();

int w,h;
...

My English is bad,hope this can help you.

ps:you really show learn some basic knowledge of c/c++

Upvotes: 0

CLL
CLL

Reputation: 331

In the new main.cpp, infile is out of scope. It only exists within the implementation of GetFileByName(). Furthermore, after you execute:

Image bo;   //create object
bo.GetFileName();

You have created an object, and opened an ifstream, with bo.GetFileName();, but you leave the ifstream opened without ever closing it. What you should do is either

(1) have GetFileName() return the ifstream infile so that you can access it within main.ccp (and perform input operations with it). That would look like this:

Image bo;   //create object
ifstream infile = bo.GetFileName(); 

or

(2) (in my opinion is the preferred option) declare the ifstream infile as a private member of your Image class so that you can implement functions to allow input from the ifstream.

class Image {
  public:
    void GetFileName();
    //methods to allow input operations from infile

  private:
    ifstream infile;
};

Either way though, you need to make sure that the ifstream stays in scope and gets closed with .close() before the program terminates!

Upvotes: 1

Ludwik
Ludwik

Reputation: 2407

The compiler is correct, infile was not declared. When calling a function, everything that happens inside it, stays inside it, so to speak. This is called local scope. THe only thing you "get out" is the return value, in your case void.

So, the best way to go here is changing your function's return type to "std::ifstream" and adding a return infile at the end of the function. Then you would do this when calling the function:

Image bo;   //create object
ifstream infile = bo.GetFileName();

int w, h;
string s;
infile >> s; 

An alternative and perhaps more universal way would be to make the function return a string, but I'm guessing there's some reason why you're using streams.

Upvotes: 0

Related Questions