2013-12-12 138 views
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; 
} 

我試圖從文本文件讀取餘額,並扣除提取的金額。指數擁有餘額的年代數。但我的文件不會覆蓋現有的值與新的一個。有什麼建議麼?使用fstream讀取和寫入同一文件

+0

爲什麼你將'balance'分配給相同的值兩次,然後覆蓋它的內容? – elyashiv

+3

請勿使用例如'while(!file.eof())',它不會像你期望的那樣工作。原因在於在輸入操作失敗之後,* eofbit標誌沒有被設置。 –

+1

你對此有何看法?什麼輸入和輸出?如果它是一個文本文件,整數可能會佔用不同數量的字符,並覆蓋它不應該的值,或者不覆蓋它應該的值。 –

回答

4

在沒有插入查找的情況下在文件流的輸入和輸出之間切換時,會出現未定義的行爲。無論你在哪裏尋找,都無所謂,但你需要尋求!例如,你可以尋求到零個字符從當前位置移開,或者更可能的是,回哪裏值真正開始的位置:

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

但是請注意,該流不會騰出空間對於其他字符,也就是說,如果讀取的內容比寫入的內容短,則會覆蓋原始輸入後的數據。同樣,你只會覆蓋你覆蓋的字符。我曾建議不要做那樣的事情。如果您想更新文件,請確保您使用的是固定寬度的記錄!

當然,你也shoudn't使用input.eof()覈實,如果流是什麼好:如果流進入故障模式,例如,由於misformatted輸入,你將永遠不會達到這種地步input.eof()產生true ,即,你會得到一個無限循環。只要使用流本身作爲條件。就個人而言,我會使用類似於

while (input >> balance && Balindex != index) { 
    ++Balindex; 
} 
+0

我明白這個問題。我改變了input.eof()行。另外,如果我單獨使用ofstream和ifstream,並將其鏈接到同一個文件,那麼使用fstream會有什麼不同?如果是,如何?哪種方式更方便?我仍然不明白seekg的概念。它究竟做了什麼? –

+0

@RJ:對同一個文件使用兩個流可能會讓事情進一步惡化,因爲每個文件都有自己的緩衝區,在某些系統上,無論如何都無法獨立打開相同的文件進行讀寫。 'seekg()'和'seekp()'分別定位流的get和put位置。對於文件流,這些操作還可以將流轉換爲可以進入讀取或寫入狀態的關聯狀態。當它處於閱讀狀態時,你不能寫;當它處於書寫狀態時,你無法閱讀(如果你嘗試,你會得到未定義的行爲)。 –

+0

我明白了。所以我會堅持fstream然後。 :) 此外,如果我試圖替換文本文件中的一行,我會查找直到該行結束,然後我將能夠輸出?所以使用getline將幫助我實現這一點,那麼對嗎? –