Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » C++ fstream problems

This thread is locked; no one can reply to it. rss feed Print
C++ fstream problems
relay01
Member #6,988
March 2006
avatar

Hi everyone,
If you look in the class constructor for Pdisk, there is a function that checks to see if a file exists, if it doesn't, then it creates it. And so far that seems to work perfectly.
At the end of the code, in the function "putblock" , I try almost the exact same thing, yet it's unable to find/open the file. This is my attempt to debug what I really wanted it to do, which is to open it, put something into the file, then close it.

Could somebody tell me what I'm doing wrong and/or show me how do it right?

The project is due Monday so I'm kindof in a bind.

1/*
2
3#include<fstream>
4#include<string>
5using namespace std;
6
7Class Pdisk
8{
9Public:
10Pdisk(int numberofblocks, int blocksize, string& diskname)
11int getblock(int blocknumber, string buffer);
12int putblock(int blocknumber, sting buffer);
13Private:
14string diskname;
15int numberofblocks;
16int blocksize;
17};
18
19*/
20 
21#include"pdisk.h"
22 
23Pdisk::Pdisk(int numberofblocks, int blocksize, string& diskname)
24{
25int countsize = 1;
26int countblocks = 2; //set to 2 to balance things out.
27fstream checkfile;
28checkfile.open(diskname.c_str(), ios::in|ios::out);
29bool there_be_no_file = checkfile.fail();
30checkfile.close();
31if(there_be_no_file == false)
32 {
33 cout<<"does this happen?"<<endl;
34 //obtain file information from boot sector and set global variables to that
35 //just in case some idiot didn't pass the correct values
36
37 }
38else
39 {
40 cout<<"or does this happen?";
41 ofstream iofile(diskname.c_str());
42 iofile<<"+"<<numberofblocks<<"+"<<blocksize<<"+"<<diskname<<endl;
43 while(countblocks <= numberofblocks)
44 {
45 while(countsize <= blocksize)
46 {
47 iofile<<"+";
48 countsize++;
49 }
50 iofile<<endl;
51 countsize = 1;
52 countblocks++;
53 cout<<"please tell me this happens"<<endl;
54 }
55 iofile.close();
56 }
57//check if file already exists, if it doesn't, then create it.
58//if it does then just use that file
59//fstream iofile;// name of file is diskname; open file for writting and such
60//if file doesn't exist, create it with the number of blocks, block size and diskname
61}
62 
63int Pdisk::getblock(int blocknumber, string& buffer)
64{
65//accepts integer for block number and name of disk and returns value as a string?
66ifstream iofile;
67iofile.open(this->diskname.c_str(), ios::in | ios::out);
68iofile.seekg(blocknumber*blocksize,ios::beg);
69for(int i = 0; i<blocksize; i++)
70 {
71
72 iofile>>i;
73 buffer+=i;
74 }
75iofile.close();
76}
77 
78int Pdisk::putblock(int blocknumber, string buffer)
79{
80fstream checkfile;
81checkfile.open(this->diskname.c_str(), ios::in|ios::out);
82bool there_be_no_file = checkfile.fail();
83checkfile.close();
84if(there_be_no_file == false)
85 {
86 cout<<"unable to open file"<<endl;
87 //obtain file information from boot sector and set global variables to that
88 //just in case some idiot didn't pass the correct values
89
90 }
91else
92 {
93 cout<<"file able to be opened";
94}
95}

_____________________________________

adam450
Member #5,460
January 2005

Post the code, make sure they are looking in the same folder. And of course make sure you call close(), when you done with each function.

bamccaig
Member #7,536
July 2006
avatar

What language is this? Why is the first letter in Class, Private, and Public uppercase? :-/

I would fail you for lack of spacing, poor formatting, and poor variable names. ;D

Also, post the entire program so we don't have to write our own implementation to debug it. :-/ And I think your example is missing a semi-colon after the constructor declaration.

relay01 said:

Class Pdisk
{
Public:
Pdisk(int numberofblocks, int blocksize, string& diskname) // OH NOES!
int getblock(int blocknumber, string buffer);

Also I think you're missing a space in the pdisk.h #include:

relay01 said:

#include"pdisk.h"

Also you named an ofstream object iofile... :-/

relay01 said:

ofstream iofile(diskname.c_str());

You should also declare your variables at the beginning of functions.

Clean up your code and come back with all of it. :D And if they are in separate files just copy and paste each into it's own set of code tags. (And format it next time)

Dustin Dettmer
Member #3,935
October 2003
avatar

... string& diskname)

Make this code into:

... const string& diskname)

Why are you trying to open files for reading and writing at the same time? IIRC windows doesn't support this.

ifstream iofile;
iofile.open(this->diskname.c_str(), ios::in | ios::out);

Why are you trying to output using an ifstream? This is not possible.

bamccaig
Member #7,536
July 2006
avatar

Dustin Dettmer said:

Why are you trying to open files for reading and writing at the same time? IIRC windows doesn't support this.

Yes it does... :-/

Yeah, looking again your code is all messed up. :-/ How about we start with what your class has to do with a disk? :-/

adam450
Member #5,460
January 2005

"there is a function that checks to see if a file exists, if it doesn't, then it creates it"

-When you call ofstream file( "filename.txt"); it already creates that file if its not a file, so why are you checking if its valid? I mean since you dont care cuz you create it anyway if it doesnt exist.

***IN your constructor for your class, you never set the data member string diskname.
So the putblock function, your trying to open a file with the member diskname, but diskname is NULL.

//yes windows suppports reading and writing. Useful for appending mainly I guess.
r - open for reading
w - open for writing (file need not exist)
a - open for appending (file need not exist)
r+ - open for reading and writing, start at beginning
w+ - open for reading and writing (overwrite file)
a+ - open for reading and writing (append if file exists)

Dustin Dettmer
Member #3,935
October 2003
avatar

Ah ok so it is supported. But do you actually need to read and write the file at the same time? Sounds like uneeded complexity if you don't actually really need it.

relay01
Member #6,988
March 2006
avatar

During the time, I got it working.
Well. Sortof.

I apologize to everyone for the lousy code. Believe it or not, though I technically wrote it, it's not my code. A lot of this stuff was copied off the board lectures in my class. Oh god, what is this guy doing? the whole class implementation in comments on the top is his, the one I'm using actually compiles and works.

My new problem is with the
seekg and seekp functions. It doesn't appear to be putting the seekp in the correct place for this function. Is there once again... a problem with my implimentation

1int Pdisk::putblock(int blocknumber, string buffer, string& diskname, int blocksize)
2{
3 
4ofstream ofile;
5ofile.open(diskname.c_str(),ios::app);
6bool there_be_no_file = ofile.fail();
7if(there_be_no_file == false)
8 {
9 cout<< blocknumber;
10 cout<< blocksize;
11 ofile.seekp(blocknumber*blocksize,ios::beg);
12 cout<<"able to open file"<<endl;
13 ofile<<buffer;
14 cout<<buffer<<endl;
15 ofile.close();
16 cout<<diskname;
17 
18 }
19else
20 {
21 cout<<"failed to open file";
22}

Now, the backstory for the code. "Pdisk" is a class that is supposed to represent a Psuedodisk, or, well, a data disk being represented by a text file. The project is to implement this. So this is where the number of blocks and block size come from. This function is supposed to go through the file and put whatever string is passed to it, into the file.

And just for the purpose of hopefully redeeming myself, here's MY class declaration.

1#define PDISK_H
2 
3#include<fstream>
4#include<string>
5#include<iostream>
6using namespace std;
7 
8 
9class Pdisk
10{
11public:
12Pdisk(int numberofblocks, int blocksize, string& diskname);
13int getblock(int blocknumber, string& buffer, string& diskname,int blocksize);
14int putblock(int blocknumber, string buffer, string& diskname,int blocksize);
15private:
16string diskname;
17int numberofblocks;
18int blocksize;
19};
20 
21#endif

_____________________________________

adam450
Member #5,460
January 2005

1st, I suggest you use gamedev.net. It's alot wider of use for non-allegro questions.

2. DO you know what a class does? you have data members such as blocksize, which you have to instantiate. So there are alot of things wrong. In your constructor:

Pdisk::Pdisk(int numberofblocks, int blocksize, string& diskname)
{
}

change those variable names like such, and of course you need to set the data members. Basically do this and it should work

Pdisk::Pdisk(int _numberofblocks, int _blocksize, string& _diskname)
{
numberofblocks = _numberofblocks;
blocksize = __blocksize;
diskname = _diskname;
int countisize = 1;
.....the rest of your code.

Dustin Dettmer
Member #3,935
October 2003
avatar

Do that OR...

Pdisk:Pdisk(int numberofblocks, int blocksize, string& diskname)
    : numberofblocks(numberofblocks), blocksize(blocksize), diskname(diskname)
{
    int countisize = 1;
    .....the rest of your code.

Anyway, back to this putblock function. Ugh! This stuff is getting messy.. Ok heres my first pass with observations:

1// You should be doing:
2// const string &diskname
3// Honestly there should never really be a need
4// to pass in a string via reference.
5int Pdisk::putblock(int blocknumber, string buffer, string& diskname, int blocksize)
6{
7 
8ofstream ofile;
9 
10// You must pass ios::out in the flags as well as ios::app
11// But honestly, I don't think you want ios::app
12ofile.open(diskname.c_str(),ios::app);
13 
14// there_be_no_file is probably a bad name here as
15// it implies the file could not be opened. It
16// actually means the file could not be created.
17bool there_be_no_file = ofile.fail();
18if(there_be_no_file == false)
19 {
20 cout<< blocknumber;
21 cout<< blocksize;
22 
23 // This does nothing since you passed ios::app to
24 // open
25 ofile.seekp(blocknumber*blocksize,ios::beg);
26 
27 cout<<"able to open file"<<endl;
28 ofile<<buffer;
29 cout<<buffer<<endl;
30 ofile.close();
31 cout<<diskname;
32 
33 }
34else
35 {
36 cout<<"failed to open file";
37}

Alright, now heres my version of the method:

1 
2int Pdisk::putblock(int blocknumber, string buffer, const string& diskname, int blocksize)
3{
4 
5ofstream ofile;
6 
7// Flags default to ios::out if we do not specify any
8ofile.open(diskname.c_str());
9 
10bool unable_to_open = ofile.fail();
11if(unable_to_open == false)
12 {
13 cout<< blocknumber;
14 cout<< blocksize;
15 if(ofile.seekp(blocknumber*blocksize,ios::beg).fail())
16 cout << "File too small to seek to this position.\n";
17 else
18 cout<<"able to open file"<<endl;
19 ofile<<buffer;
20 cout<<buffer<<endl;
21 ofile.close();
22 cout<<diskname;
23 
24 }
25else
26 {
27 cout<<"failed to open file";
28}

Go to: