1
void Withdraw(int index, int amount) { int Balindex = 0; fstream input("Balance.txt"); float balance = 0.0; while ((!input.eof())&&(Balindex != index)) { balance = 0.0; input >> balance; Balindex++; } input >> balance; balance = balance - amount; input << balance << endl; } 

i am trying to read balance from a text file, and deduct the amount withdrawn. index holds the chronological number of the balance. my file however wont overwrite the existing value with the new one. Any suggestions?

4
  • why are you assigning balance twice to the same value and then overriding it's contents? Commented Dec 12, 2013 at 13:47
  • 3
    Don't use e.g. while (!file.eof()), it won't work as you expect it to. The reason being that the eofbit flag isn't set until after an input operation fails. Commented Dec 12, 2013 at 13:47
  • 1
    What do you expect this to do? What input and output? If it's a text file, the integer is likely to take up differing amounts of characters, and overwrite values it shouldn't, or not overwrite values it should. Commented Dec 12, 2013 at 13:52
  • i changed the !file.eof(). My text file has balance for several accounts. This code is basically a part of an ATM machine. inputs are taken, until the balance of the user is reached. i am doing this using "index". once, the balance of the user is read, the amount is deducted from it, and then i am trying to overwrite the prev balance with the new one. True, the integer is likely to take up differing amounts of characters. would using getline() help me in any way? Commented Dec 12, 2013 at 14:11

1 Answer 1

4

When switching between input and output for a filestream without an intervening seek, you get undefined behavior. It doesn't matter where you seek to but you need to seek! For example, you can seek to zero characters away from the current position or, more likely, back to the position where the value actually started:

std::streampos start = input.seekg(0, std::ios_base::cur); if (input >> balance) { input.seekp(start); input << (balance - amount); } 

Note, however, that the stream won't make space for additional characters, i.e., if what you read is shorter than what you write, you'll overwrite data following the originla input. Likewise, you will only overwrite the characters you overwrite. I'd recommened against doing anything like that. If you want to update a file, make sure you are using fixed width records!

Of course, you also shoudn't use input.eof() to verify if the stream is any good: if the stream goes into failure mode, e.g., due to a misformatted input, you'll never reach the point where input.eof() yields true, i.e., you'd get an infinite loop. Just use the stream itself as condition. Personally, I would use something like

while (input >> balance && Balindex != index) { ++Balindex; } 
Sign up to request clarification or add additional context in comments.

7 Comments

i understand the problem. i changed the input.eof() line. also, if i use ofstream and ifstream seperately, and link it to the same file, will it be any different that just using an fstream? If yes, how? and which way is more convinient to do? i still don't understand the concept of seekg. What does it do exactly?
@RJ: Using two stream to the same file is likely to mess things up further because each file will have its own buffer and on some systems you can't open the same file for reading and writing independently anyway. seekg() and seekp() position the get and put location, respectively, of the stream. For file streams these operations also get the stream into an associated state where it can go to either reading or writing state. When it is in reading state, you can't write; when it is in writing state you can't read (if you try, you get undefined behavior).
i see. so i am gonna stick to fstream then. :) Also, if i am trying to replace a line in a text file, will i seekp until the end of that line, and then i will be able to output? so using getline will help me achieve this then right?
@RJ: possibly. You should make sure that all your lines are exactly the same length. As I said before, I'd recommend against what you are trying to do. Use a database instead.
i understand. i really want to be done with this project. but, for future purposes, i will definitely use something more efficient. now that i think about it, i should have just used a struct with vectors to hold everything. You are a genius. :D
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.