2

I want to operate on streams using some abstraction and thus I want to use fstream* instead of ifstream and ofstream. I tried to do sth like that but is wil cause access violation:

char* text= "test"; 
fstream* o = new fstream(); 
o = &fstream("name.txt"); 
o->write(text, 4); 
o->close();

How can I fix it, or use another idea ?

I want to use pointer in this case (You can look here for more general information) How to implement my own IO file API in C++

After the changes it now looks like this:

class GIO_Persistent_File_System : public GIO_CORE
{
public:
GIO_Persistent_File_System(void);
int open(char*, int);
int close();
void write(char* s, int size);
void read(char* s, int size);
public:
~GIO_Persistent_File_System(void);

private:
fstream file;
};

int GIO_Persistent_File_System::open(char* path, int mode){
file.open(path);
return 0;
}

int GIO_Persistent_File_System::close(){
file.close();
return 0;
}

void GIO_Persistent_File_System::write(char* s, int size){
file.write(s, size);
return;
}

void GIO_Persistent_File_System::read(char* s, int size){
file.read(s, size);
return;
}

MAIN:

GIO_CORE* plik = new GIO_Persistent_File_System();
char* test = new char[10];
char* napis = "testgs";
plik->open("name.txt", OPEN_MODE);
plik->write(napis, 2);
//plik->read(test,2);
plik->close();

And this code seems like working altough I cannot find the file. I checked and the current directory is pointed correctly (ProjectName/Debug)

I checked it and changing fstream to ofstream will works as it should and I can find the file. But since I want to achieve some level of abstraction and I would like to use fstream. How can I fix it ?

Community
  • 1
  • 1
rank1
  • 1,018
  • 4
  • 16
  • 37

2 Answers2

7

This code will give you an error, since you can't take the address of a temporary object, as you are doing with &fstream("name.txt").

error: taking address of temporary

Also, note that the conversion from a string literal to a char* has been deprecated and is invalid in C++11. Use a const char* instead:

const char* text = "test";

Nonetheless, let's look at what you're trying to do. Firstly, you are dynamically allocating an fstream and initialising a pointer to that object:

fstream* o = new fstream();

Then in the next line, you create a temporary object with fstream("name.txt") and then take its address and assign it to o (which gives an error, as we've seen). Now you would have lost any access to the dynamically allocated fstream and instead have o pointing at a now destroyed temporary object.

Dereferencing that pointer (with o->) will give you undefined behaviour.

You are overcomplicating this. You do not need to dynamically allocate your fstream object or use pointers at all. Instead, try:

fstream o("name.txt");
o.write(text, 4);
o.close();

With your updated code, the problem is that you are writing 0 bytes:

plik->write(napis, 0);

Perhaps you meant:

plik->write(napis, 6);
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • If I use fstream o as You said and initialize it in header file of my class. And then in Open(char* path) in my class try to do o = fstream(path) it will cause compilation errors. That's why I wanted to use pointer – rank1 Mar 28 '13 at 14:25
  • 1
    @SebastianCygert You should just be doing `o.open(path)`. – Joseph Mansfield Mar 28 '13 at 14:26
  • It seems like working (no errors) but actually no file is created in the directory. As it was created with your solution fstream o("name.txt"); o.write(text, 4); o.close(); – rank1 Mar 28 '13 at 14:33
  • @SebastianCygert Edit your new code into the question exactly as is. Do not modify it. – Joseph Mansfield Mar 28 '13 at 14:40
  • @SebastianCygert The problem is that you're passing a size of 0: `plik->write(napis, 0);` – Joseph Mansfield Mar 28 '13 at 14:49
  • @sftrabbit - look at the new edit just at the end of the question – rank1 Mar 28 '13 at 15:47
  • 1
    @SebastianCygert I believe you might be seeing a Visual Studio bug. Try `file.open(path, std::fstream::in | std::fstream::out | std::fstream::trunc);` – Joseph Mansfield Mar 28 '13 at 16:01
  • Oops, sorry I just reordered our comments there. There's a VS bug where the `std::fstream::in` forces it to be an input file only, even if you specify `std::fstream::out`. `std::fstream::trunc` for some reason forces it back again. – Joseph Mansfield Mar 28 '13 at 16:02
  • Ok, this is really amazing. Made my day – rank1 Mar 28 '13 at 16:03
  • For opening I can just put file.open(path). But for writing I have to use your fix. Is there a way to open a file for both operations ? – rank1 Mar 28 '13 at 16:08
  • 1
    Even though the answer is technically correct for the given example, it doesn't answer the question how to instantiate a stream object using new. – Devolus Oct 20 '20 at 08:00
2

There's hardly ever need to have a pointer to fstream. Just do this:

std::ofstream o("name.txt");
o.write(napis, 4);
o.close();

Notice that o will also close when it goes out of scope, so often you don't even have to call close().

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455