Thread: fstream is just not working for me..

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    47

    fstream is just not working for me..

    I've been having a lot of problems with fstream lately..
    for my class theres this source code that won't compile... i was hoping someone could help me shed some light...

    Code:
    #include<iostream>
    #include<fstream>
    using namespace std;
    
    void adding(fstream & f, int & counter)
    {
    	char name[51];
    	long l = f.tellp() / 50; // find out how many records are in the file (Each I record consumes 50 bytes.)
    	cout << "There are " << l << " records in the file." << endl;
    	cout << "Enter a name ";
    	cin.getline(name, 50);
    	f.seekp(counter * 50); // move the pointer to the last position.
    	f.write(name, 50); // write 50 bytes to the file.
    	counter++; // increase the counter.
    }
    
    void displaying(fstream & f)
    {
    	int r=0;
    	char name[51];
    	cout << "Which record do you want to read ?";
    	cin >> r;
    	cin.ignore(200, '\n');
    	f.seekg(--r * 50); // locate the pointer for the read() function.
    	f.read(name, 50); // read 50 bytes from the file and store it into 'name'
    	cout << "The name is " << name << endl;
    }
    
    
    void changing(fstream & f)
    {
    	int r=0;
    	char name[51];
    	cout << "Which record do you want to change ?";
    	cin >> r;
    	cin.ignore(200, '\n');
    	cout << "Enter a name ";
    	cin.getline(name, 50);
    	f.seekp(--r * 50);
    	f.write(name, 50);
    }
    
    
    int main()
    { // open a binary file for both input and output.
    	fstream f("Test.bin", ios::in | ios::out | ios::binary);
    	int i=0;
    	int counter=0;
    	if(f) { // the file can open.
    		while(i != 4) {
    		cout << "1 for adding records " << endl;
    		cout << "2 for displaying records " << endl;
    		cout << "3 for changing records " << endl;
    		cout << "4 for quitting the program" << endl;
    		cin >> i;
    		cin.ignore(200, '\n');
    		if(i==1)
      	  	  	adding(f, counter);
    		else if(i==2)
    			displaying(f);
    		else if(i==3)
    			changing(f);
    		}
    	}
    	else
    		cout << "failed" << endl;
    	f.close(); // close the file associated with "f"
    	return 0;
    }
    all i get in the console window is

    Code:
    failed
    press any key to continue .....
    please let me know why this is happening..
    also as a side note. while learning fstream i have had many failed attempts in opening an fstream with both ' ios::in and ios:ut '.. perhaps there's a relationship between them. or i just dont know my fstream well enough..

    thanks

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The way you're opening the file, Test.bin must exist. You don't use a full path, so it must exist in the current directory. But the current directory is often different than the directory that your program is in, and can change depending on how you run the program.

    Put a full path in the code (e.g. "C:\\test.bin") and see if it works better. If it does, then you just need to make sure the current directory is what you expect.

    If you're running from Visual C++, edit the Project Properties under Debugging and change the Working Directory to the directory that has that file. If you're running from the command line, then set the current directory of the console to the directory with your file before running the program. If you're doing something else, let us know so we can help.

    If the full path doesn't work, make sure the file exists there and is readable and writable, and make sure you used the proper escape sequence for directory separators.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by MegaManZZ View Post
    I've been having a lot of problems with fstream lately..
    for my class theres this source code that won't compile... i was hoping someone could help me shed some light...
    The code compiles just fine in the Comeau compiler.

    Quote Originally Posted by MegaManZZ View Post
    all i get in the console window is

    Code:
    failed
    press any key to continue .....
    please let me know why this is happening..
    also as a side note. while learning fstream i have had many failed attempts in opening an fstream with both ' ios::in and ios:ut '.. perhaps there's a relationship between them. or i just dont know my fstream well enough..

    thanks
    Obviously the "Test.bin" file couldn't be opened. Check if the file exists in the current directory of your program and that you have read/write access to it.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  4. #4
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    I suspect that you probably want to open the file with the append flag set as well, that way, if the file doesn't already exist, it gets created empty.
    Code:
    fstream f("Test.bin", ios::in | ios::out | ios::binary | ios::app);
    Also,
    Code:
    if (f) {
    ...
    }
    makes me uneasy. Maybe that works, maybe it doesn't, but I would much rather see you checking the bad/fail flags using f.fail()
    [edit]
    Maybe someone else can shed light on this. I know checking "if (!f) {}" will work, because the ! operator is overloaded. And doing an explicit cast to void* pointer should work as well: "if ((void*)f == 0) {}". But will "if (f) {}" work?
    [/edit]

    Finally, your code doesn't seem to do bounds checking in all cases. If the file only contains 5 records, and I tell it to display record 10, what is it going to do...?
    Last edited by arpsmack; 09-28-2008 at 10:10 PM.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> But will "if (f)" work?
    Yes. The conversion to void* is done automatically, and that value is evaluated in the boolean context to be false if the file did not open.

    >> I suspect that you probably want to open the file with the append flag set as well, that way, if the file doesn't already exist, it gets created empty.
    I'm not sure about this, but I don't think the file is emptied when the ios::in flag is set. Otherwise how would you be able to read from the file?

  6. #6
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Quote Originally Posted by Daved View Post
    Yes. The conversion to void* is done automatically, and that value is evaluated in the boolean context to be false if the file did not open.
    Thanks! I never knew that. To me that kind of code looks scary, because if you don't understand how the language works in that situation, it can be one of those, "Oh god #!#$#, what the heck does this do?" moments. And even after digging through the documentation for a couple minutes, you're still not sure how or why it works.

    Quote Originally Posted by Daved View Post
    I'm not sure about this, but I don't think the file is emptied when the ios::in flag is set. Otherwise how would you be able to read from the file?
    Well I didn't really mean it gets emptied. If the file already exists then it gets opened for appending. If the file doesn't exist, it gets created empty.

    I just compiled his code with the append flag included just to make sure I'm not making things up here, and it worked for me (using MinGW). Of course this could just be a fluke.

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Streams provide a conversion to void* operator, so they can be evaluated in boolean contexts but not used for much anything else. Such usage of streams is perfectly normal in C++ and nothing to be afraid of.

    Here's a class that also allows to evaluate the validity of the object in a similar way (not that this is the best way to do it):

    Code:
    #include <cassert>
    
    class LimitedUsability
    {
        unsigned usage_left;
    public:
        LimitedUsability(unsigned n): usage_left(n) {}
        void do_something()
        {
            assert(usage_left > 0);
            --usage_left;
            std::cout << "doing something, can be called " << usage_left << " more times.\n";
        }
        operator const void* ()const { return usage_left ? this : 0; }
    };
    
    int main()
    {
        LimitedUsability sth(10);
        while (sth) {
            sth.do_something();
        }
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I thought they use an operator bool() function to be able to test things like if ( fp ) or if ( !fp )
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I thought they use an operator bool() function to be able to test things like if ( fp ) or if ( !fp )
    operator bool() has an obvious problem: it means that the object is convertible to int, which is often undesirable. operator void* is somewhat better, but perhaps best is the safe bool idiom.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by laserlight View Post
    operator bool() has an obvious problem: it means that the object is convertible to int, which is often undesirable.
    Could you explain this a little more or provide a link or something? Why is converting to an int undesirable?

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by robwhit
    Could you explain this a little more or provide a link or something? Why is converting to an int undesirable?
    My link to that article on the safe bool idiom explains more, and also provides examples of why conversion to void* is still not satisfactory.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Aha. Thanks. Thought it was just on that idiom alone.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with fstream, one variabile for write and read
    By Smjert in forum C++ Programming
    Replies: 3
    Last Post: 02-03-2009, 10:19 PM
  2. Fstream. I/O
    By kevinawad in forum C++ Programming
    Replies: 2
    Last Post: 07-07-2008, 09:19 AM
  3. using fstream
    By swgh in forum C++ Programming
    Replies: 1
    Last Post: 02-11-2006, 04:53 AM
  4. Program Not working Right
    By raven420smoke in forum C++ Programming
    Replies: 2
    Last Post: 09-16-2005, 03:21 AM
  5. cygwin -> unix , my code not working properly ;(
    By CyC|OpS in forum C Programming
    Replies: 4
    Last Post: 05-18-2002, 04:08 AM