file creation problem in Windows using fstream

B

Brandon McCombs

This may be the wrong group but I didn't see anything for VC++ so I'm
trying here.

I have a C++ book by Deitel and Deitel that says I can use fstream
File("data.dat", ios::in | ios::eek:ut | ios::binary) to declare a file
object with read/write modes turned on for working with binary data.
I've tried this and my file is not created. The only time it is created
is when I specify ifstream or ofstream but not fstream. I've tried
removing the binary mode and it doens't make a difference. The
following is sample code I created to just test to see whether g++ in
Linux and VC++ 6.0 in Windows XP could handle the code:

#include <all appropate files>

using std:: all appropriate statements;


void main ()
{

char fd[255];
int entries;
char *entry = "f";
cout << "Enter the filename for performing operations: " << endl;
cin >> fd;
fstream dataFile(fd, ios::eek:ut | ios::in | ios::binary );

cout << "How many entries would you like for the file to hold? " <<
endl;
cin >> entries;

for (int i = 0; i < entries; i++)
dataFile.write(reinterpret_cast<const char *>(&entry), sizeof(char));


entry="g";
cout << entry << endl;
dataFile.seekg(0);
dataFile.read(reinterpret_cast<char *>(&entry), sizeof(char));
cout << entry << endl;
}

The file is initalized with "f" and then the "entry" variable is set to
"g". If the file is created properly and can be read then "entry" is
assigned "f" from the file. g++ compiles this progrma fine and upon
execution the file is created and initalized, so a "g" and then a "f" is
printed out. In Windows XP Visual C++ 6 will compile it but my file is
not created. I have a project due next Friday where I'm trying to do
this and I odn't know why it's not working. THe professsor uses VC++6
and he doesn't have problems and I'm doing the same thing the book is
doing from what I can tell. Does anyone know what VC++ is wanting that
I'm not doing?

As a workaround I tried to open a file in read mode using ifstream
declaration and then close the file after reading is done and reopen the
file with write mode using ofstream. That works as far as the file
being created however the contents of the file from a write operation
are discarded once I reopen the file and I think that's stupid behavior.
What happens if a user wants to write to multiple files during a single
execution of a program? If they write to one file then another, and come
back to the original the contents are discarded and they lost all their
work. But anyway, using the ios::append mode just puts my data at the
end of the file and since this has to be random access that is not going
to cut it. Using seekg() and seekp() to override default writing at the
eend of the file was not sucessful. I'm out of options unlesss someone
can give some pointers. (no pun intended)

thanks for any help
Brandon
 
P

P.J. Plauger

I have a C++ book by Deitel and Deitel that says I can use fstream
File("data.dat", ios::in | ios::eek:ut | ios::binary) to declare a file
object with read/write modes turned on for working with binary data.
I've tried this and my file is not created. The only time it is created
is when I specify ifstream or ofstream but not fstream. I've tried
removing the binary mode and it doens't make a difference. The
following is sample code I created to just test to see whether g++ in
Linux and VC++ 6.0 in Windows XP could handle the code:

#include <all appropate files>

using std:: all appropriate statements;


void main ()
{

char fd[255];
int entries;
char *entry = "f";
cout << "Enter the filename for performing operations: " << endl;
cin >> fd;
fstream dataFile(fd, ios::eek:ut | ios::in | ios::binary );

cout << "How many entries would you like for the file to hold? " <<
endl;
cin >> entries;

for (int i = 0; i < entries; i++)
dataFile.write(reinterpret_cast<const char *>(&entry), sizeof(char));


entry="g";
cout << entry << endl;
dataFile.seekg(0);
dataFile.read(reinterpret_cast<char *>(&entry), sizeof(char));
cout << entry << endl;
}

The file is initalized with "f" and then the "entry" variable is set to
"g". If the file is created properly and can be read then "entry" is
assigned "f" from the file. g++ compiles this progrma fine and upon
execution the file is created and initalized, so a "g" and then a "f" is
printed out. In Windows XP Visual C++ 6 will compile it but my file is
not created. I have a project due next Friday where I'm trying to do
this and I odn't know why it's not working. THe professsor uses VC++6
and he doesn't have problems and I'm doing the same thing the book is
doing from what I can tell. Does anyone know what VC++ is wanting that
I'm not doing?

As a workaround I tried to open a file in read mode using ifstream
declaration and then close the file after reading is done and reopen the
file with write mode using ofstream. That works as far as the file
being created however the contents of the file from a write operation
are discarded once I reopen the file and I think that's stupid behavior.
What happens if a user wants to write to multiple files during a single
execution of a program? If they write to one file then another, and come
back to the original the contents are discarded and they lost all their
work. But anyway, using the ios::append mode just puts my data at the
end of the file and since this has to be random access that is not going
to cut it. Using seekg() and seekp() to override default writing at the
eend of the file was not sucessful. I'm out of options unlesss someone
can give some pointers. (no pun intended)

From our online documentation:

basic_filebuf *open(const char *filename,
ios_base::eek:penmode mode);

The member function endeavors to open the file with filename filename,
by calling fopen(filename, strmode). Here strmode is determined from
mode & ~(ate & | binary):

-- ios_base::in becomes "r" (open existing file for reading).

-- ios_base::eek:ut or ios_base::eek:ut | ios_base::trunc becomes "w"
(truncate existing file or create for writing).

-- ios_base::eek:ut | ios_base::app becomes "a"
(open existing file for appending all writes).

-- ios_base::in | ios_base::eek:ut becomes "r+"
(open existing file for reading and writing).

-- ios_base::in | ios_base::eek:ut | ios_base::trunc becomes "w+"
(truncate existing file or create for reading and writing).

ios_base::in | ios_base::eek:ut | ios_base::app becomes "a+"
(open existing file for reading and for appending all writes).

If mode & ios_base::binary is nonzero, the function appends b to strmode
to open a binary stream instead of a text stream. It then stores the
value returned by fopen in the file pointer fp. If mode & ios_base::ate
is nonzero and the file pointer is not a null pointer, the function calls
fseek(fp, 0, SEEK_END) to position the stream at end-of-file. If that
positioning operation fails, the function calls close(fp) and stores a
null pointer in the file pointer.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
B

Brandon McCombs

So how does all this help me? I know all the modes. The only one I havent
tried is the truncate mode and that gets rid of the file's contents as well so
what are you suggesting, if anything?
 
P

P.J. Plauger

Brandon McCombs said:
So how does all this help me? I know all the modes. The only one I havent
tried is the truncate mode and that gets rid of the file's contents as well so
what are you suggesting, if anything?

I'm suggesting you RTFM. You said:
I have a C++ book by Deitel and Deitel that says I can use fstream
File("data.dat", ios::in | ios::eek:ut | ios::binary) to declare a file
object with read/write modes turned on for working with binary data.
I've tried this and my file is not created.

And I wrote:

-- ios_base::in | ios_base::eek:ut becomes "r+"
(open existing file for reading and writing).

-- ios_base::in | ios_base::eek:ut | ios_base::trunc becomes "w+"
(truncate existing file or create for reading and writing).

Deitel and Deitel have many errors in their writings, and g++ does
not score high on conformance. None of that excuses an inability
to read documentation. If you want to *create* a file, then choose
the mode that says a file gets created. Duh.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
B

Brandon McCombs

P.J. Plauger said:
And I wrote:

-- ios_base::in | ios_base::eek:ut becomes "r+"
(open existing file for reading and writing).

-- ios_base::in | ios_base::eek:ut | ios_base::trunc becomes "w+"
(truncate existing file or create for reading and writing).

Deitel and Deitel have many errors in their writings, and g++ does
not score high on conformance. None of that excuses an inability
to read documentation. If you want to *create* a file, then choose
the mode that says a file gets created. Duh.

i AM using a mode that creates a file. By default ios::eek:ut creates a file if it
doesn't already exist and when using ofstream ("data.dat", ios::eek:ut |
ios::binary) the file DOES in fact get created and i can even leave out the
ios::eek:ut part since thats the default behavior for ofstream but supposedly i can
use fstream and it creates or opens a file with both read/write access but that
doesn't happen in windows. As long as I use fstream no file is created. I'd
like to use fstream so i don't have to constantly be opening a file with read
access, closing it, then having to reopen it to write to it within the same
function and even that is a problem b/c when I open a file with write access
using ios::eek:ut the behavior of that is to delete the existing contents whcih is
not what I want done. Using ios::ate and ios::app did not work as intended
based upon the defintions for them in the Deitel book. Using ios::ate still
erased the existing contents and using ios::app just forced the content to go at
the end of the file which is stupid since i used seekp() to define where I
wanted the data to be wrtten.

from what i can tell there is no middle ground for opening a file w/o its
contents being discarded and to write to that file wherever i want. I either
lose the data or I keep the data but am forced to write at the end, which is not
useful for random read/write access.
 
P

P.J. Plauger

i AM using a mode that creates a file. By default ios::eek:ut creates a file if it
doesn't already exist and when using ofstream ("data.dat", ios::eek:ut |
ios::binary) the file DOES in fact get created and i can even leave out the
ios::eek:ut part since thats the default behavior for ofstream but supposedly i can
use fstream and it creates or opens a file with both read/write access but that
doesn't happen in windows.

If you'll stop hyperventilating and reread what I quoted before, you'll
see that there is a way to do what you want. If you want to create a
file and then be able to read and write it, the C++ Standard requires
that you specify in|out|trunc. You got away without the trunc on a
system that doesn't conform well to the C++ Standard. But now you know
the portable way to do what you want.
from what i can tell there is no middle ground for opening a file w/o its
contents being discarded and to write to that file wherever i want. I either
lose the data or I keep the data but am forced to write at the end, which is not
useful for random read/write access.

which sounds like exactly what you're asking (this time). Before, you

RTFM. (The F isn't always silent.)

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
B

Brandon McCombs

If you'll stop hyperventilating and reread what I quoted before, you'll
see that there is a way to do what you want. If you want to create a
file and then be able to read and write it, the C++ Standard requires
that you specify in|out|trunc. You got away without the trunc on a
system that doesn't conform well to the C++ Standard. But now you know
the portable way to do what you want.

I tried the ios::trunc and it did indeed create the file so I thank you for
that. Based on what the Deitel book says it makes no mention of the file being
created if it doesn't already exist when using trunc. I have to wonder why the
standards people required that to be there but stupider things have been created
I guess in the world of CS. I tried using ios::in | ios::eek:ut to open a file for
reading and writing and it just deletes the contents of my file which I do not
want. The data I'm writing is placed in the right location since I'm using
seekp() but I only get to keep the last set of data I write and only until I
open the file again. Using ate and app did not help. Am I missing something
else?
which sounds like exactly what you're asking (this time). Before, you

Actually I mentioned this problem in the last paragraph of the original post. I
may be able to open the file for reading but that is pointless when the data is
erased upon the opening action and thus there is nothing left to read.
 
P

P.J. Plauger

I tried the ios::trunc and it did indeed create the file so I thank you for
that. Based on what the Deitel book says it makes no mention of the file being
created if it doesn't already exist when using trunc.

As I said before Deitel^2 is not the most precise book around.
I have to wonder why the
standards people required that to be there but stupider things have been created
I guess in the world of CS.

Look, you want to open a file for read and write, sometimes starting
afresh and sometimes retaining the existing file. What's so stupid
about using trunc to distinguish the two cases? Do you have a better
suggestion?
I tried using ios::in | ios::eek:ut to open a file for
reading and writing and it just deletes the contents of my file which I do not
want.

Well I just tried it and it doesn't. Perhaps you should repeat your
experiment, a bit more carefully.
The data I'm writing is placed in the right location since I'm using
seekp() but I only get to keep the last set of data I write and only until I
open the file again. Using ate and app did not help. Am I missing something
else?

Evidently. My test code does exactly what the documentation I quoted
says.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
D

Dave O'Hearn

P.J. Plauger said:
Brandon McCombs said:
[OP question about Deitel&Deitel example]

If you'll stop hyperventilating and reread what I quoted before, you'll
see that there is a way to do what you want. If you want to create a
file and then be able to read and write it, the C++ Standard requires
that you specify in|out|trunc. You got away without the trunc on a
system that doesn't conform well to the C++ Standard. But now you know
the portable way to do what you want.

I've been searching for an answer to a related question recently. I
generally go around using in|out mode for a matchup to the C fopen in
"r+" mode. I have a batch of files I want opened for both input and
output, and I want a failure on a non-existant file; I don't want an
empty file to be created.

It is definately non-fashionable for in|out mode to create an empty
file instead of failing, if the file doesn't exist. All modern
compilers I use make in|out mode equivalent to the "r+" mode on fopen.
But I was unable to find any text in the Standard saying it is
actually non-standard for an implementation to create the empty file.

This has been bugging me, because I have an ancient target platform
that creates empty files on in|out. There is a non-standard flag I can
send to stop it. If creating the empty file on in|out is non-standard,
I am willing to use conditional compilation to fix this problem on
this one platform. But if it is only non-fashionable to create the
file, I am probably stuck with the bloated hack of doing two opens for
every in|out file I want, the first one being a separate test for
existance with 'in' mode.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

problem with fstream 3
fstream - write a file 3
eof error using '>>' in fstream 2
fstream Buffers 26
fstream File i/o 1
fstream problem 3
fstream.. 3
fstream, getline() and failbit 15

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top