0

I'm trying to write a programme that opens a file and uses it to make a table which is called "plansza" in our part of code we have to define a constructor

Plansza::Plansza(char * Nameoffile)

but how can we later use our name of file to actually open it?? In int main() should it be something like

Plansza plansza("text.txt")

But that's not working..

Besides this we also want to be able to use that table later, like changing some numbers or sth like that.. So we have to know where there is . and where 0

Our example file text.txt looks like this

 0......0
 ...0....
 ...0....
 ...0....
 0......0

and here is our code..

class Plansza{
    private:
        int *ekran;
        int szer;
        int wys;
    public:
        Plansza();
        Plansza(int m,int n);
        Plansza(const Plansza &plansza);
        ~Plansza();
        Plansza& operator=(const Plansza& plansza);
        Plansza(char* NazwaPliku);
        void Wyswietl();
        int Szerokosc();
        int Wysokosc();
        void Set(int x,int y,int k);
        int Get(int x,int y);
    };

Plansza::Plansza(){
    ekran=new int[12];
    szer=4;
    wys=3;
    for (int i=0;i<szer*wys+1;i++)
        ekran[i]=0;
}
Plansza::Plansza(const Plansza &plansza){
    wys=plansza.wys;
    szer=plansza.szer;
    ekran=new int[wys*szer];
    for (int i=0;i<wys*szer+1;++i)
        ekran[i]=plansza.ekran[i];
}
Plansza::~Plansza(){
    delete []ekran;
}
Plansza& Plansza::operator=(const Plansza& plansza){
    if (&plansza==this)
        return *this;
    if (ekran != NULL)
        delete []ekran;
    szer=plansza.szer;
    wys=plansza.wys;
    ekran=new int[szer*wys];
    for (int i=0; i<szer*wys+1; i++)
        ekran[i]=plansza.ekran[i];
    return *this;
}
Plansza::Plansza(int m,int n){
    ekran=new int[m*n];
    szer=n;
    wys=m;
    for (int i=0;i<m*n+1;i++)
        ekran[i]=0;
}
Plansza::Plansza(char* NazwaPliku){
    FILE * plik;
    plik= fopen("Test.txt", "r");
    fclose(plik);
};
 void Plansza::Wyswietl(){
    for (int i=1;i<szer*wys+1;i++)
    {
        if (i%(szer)==0){
            if (ekran[i]==0)
                cout<< "." <<"";
            else
                cout<< "X" <<"";
            cout<< "\n" <<"";
        }
        else
        {
            if (ekran[i]==0)
                cout<< "." <<"";
            else
                cout<< "X" <<"";
        }
    }
};
int Plansza::Szerokosc(){
    return szer;
};
int Plansza::Wysokosc(){
    return wys;
};
void Plansza::Set(int x,int y,int k){
    if ((x>wys) || (y>szer) || (x<1) || (y<1))
        cout<<"Jestes poza tablica"<<"\n";
    else
        ekran[(x-1)*szer+y]=k;
}; 
int Plansza::Get(int x,int y){
if ((x<=wys) && (y<=szer)  && (x>=1) && (y>=1))
    return ekran[(x-1)*szer+y];
else
{
    cout<<"Jestes poza tablica"<<"\n";
    return 0;
}
};
  • What exactly do you mean by 'but that's not working'? You could copy the constructor's argument to an instance variable for later reference. – Codor Jan 19 '15 at 14:17
  • 1
    As a side note, [you should not do actual work in your constructor](http://stackoverflow.com/questions/2399619/should-a-c-constructor-do-real-work), including file reading. – Cory Kramer Jan 19 '15 at 14:19
  • "But that's not working.." - what exactly goes wrong? (You'll need `const char *` (or `std::string`), not `char *`, for a modern compiler, and you'll need to write the constructor properly, not just open and close a file with a different name to the one provided. But apart from that, there's nothing obviously wrong). – Mike Seymour Jan 19 '15 at 14:20
  • What's the use of fopen immediately followed by fclose (without fread)? BTW, consider using vector instead of int* for ekran. – Werner Henze Jan 19 '15 at 14:20
  • 1
    @Cyber: Why shouldn't the constructor initialise it completely? The alternative is to leave it in a ghastly undead state until you call a second-stage initialiser. That's much worse, in my opinion. (And the accepted answer in your link agrees with me.) – Mike Seymour Jan 19 '15 at 14:21
  • 1
    Use a vector and you don't need to write your own destructor, copy constructor or assignment operator any more. – Neil Kirk Jan 19 '15 at 14:31
  • @MikeSeymour, a better alternative [than fat constructors and two-stage initialization) is a factory function: perform all operations that can fail in the factory function, and if they all succeed, return the object. If they fail, everything is fine because RAII. This will allow you to construct the class dependencies differently in different scenarios (using - for example - separate factory function for production and test code) and the constructor remains thin/safe. – utnapistim Jan 19 '15 at 14:33
  • Your assignment operator is not exception-safe (if the `new` throws then `ekran` is left pointing to garbage, which will then be double-deleted in the destructor). Also, why are you using `new int [12]` instead of a `array` or `vector`? – Jonathan Wakely Jan 19 '15 at 17:23
  • Yes I know that I'm ignoring that argument and that's exactly my problem! because with 'NazwaPliku' instead of the name of that particular file creates an error, so the way you wrote it, is not compiling at all.. Our constructor was aimed at just creating a table containing date from that file, so I still think that the whole process of opening that file should stay in that place not in main There is no point in opening it and closing it right after.. it is just the place where I don't know what should be there, I want to read the file so that my table will be exactly the table from that file – user3608938 Jan 19 '15 at 21:06
  • So I can create a table in my main function saying for example Plansza plansza(3,5) and it will be filled by default and I want to be able to write Plansza plansza(Text.txt) so that it will be filled with data contained in my file!! – user3608938 Jan 19 '15 at 21:07

1 Answers1

2

You're ignoring the NazwaPliku argument, instead hardcoding "Test.txt". Instead:

Plansza::Plansza(char* NazwaPliku){
    FILE * plik;
    plik= fopen(NazwaPliku, "r");
    fclose(plik);
};

If you want to access the file later, you need to store it in a field in the object. You already have ekran, szer and wys, so presumably you know how to do that.

(Now I want to learn Polish so I can use such charming identifiers in my code... :))

Thomas
  • 174,939
  • 50
  • 355
  • 478