[英]Overwrite a line with ofstream C++
我正在做一個小游戲,並將玩家詳細信息保存在txt文件中。 該txt文件的示例:
Eric 13 8 10 10 30 10 10 50 0 0 0 0
William 1 0 10 30 30 10 10 50 0 0 0 0
John 1 0 10 30 30 10 10 50 0 0 0 0
這就是我的初衷:當玩家選擇在玩游戲時保存游戲時, save_game
函數應檢查是否已經有保存的數據。 如果有的話,它應該overwrite
該特定行,而不是將數據附加到txt的末尾。
這是我當前的功能:
// SAVE GAME
void save_game(Player player)
{
ofstream coutfile (SaveDestiny, ios::app);
if (coutfile.is_open()) // if it opens correctly
{
// Now checking if the name already exists
string imported_name;
ifstream cinfile (SaveDestiny); // opens file that contains the saved games
cinfile >> imported_name; // getting first element of file
bool j = 0; // j = 0 while the strings don't match. j = 1 when the string was found
while (cinfile >> imported_name) // while the end of file is not reached
{
if (player.name.compare(imported_name) == 0) // if the strings are the same, overwrite data
{
j = 1;
coutfile << " \r" << endl;
break;
}
else // if the strings are different, keep reading
{
cinfile >> imported_name;
}
}
// Continuing...
coutfile << player.name << " " << player.level << " " << player.exp << " " << player.max_exp << " "
<< player.hp << " " << player.max_hp << " " << player.mp << " " << player.max_mp << " "
<< player.gold << " " << player.weapon << " " << player.shield << " " << player.heal_spell << " "
<< player.attack_spell << endl;
}
else
{
ofstream coutfile (SaveDestiny, ios::app);
coutfile << "test";
cout << "Unable to open file";
cin.get();
}
draw_rectangle(37,8,72,14,15); // white limits
draw_rectangle(39,9,70,13,9); // blue background
cor(9,15);
gotoxy(50,10);
cout << "GAME SAVED!";
gotoxy(41,12);
cor(9,14);
cout << "Press <Enter> to continue... ";
cin.get();
}
在大多數現代文件系統上,文件不是基於行的(或基於記錄的),而是基於字符的,因此您不能“覆蓋行”。 舊行可能長20個字符,而新行可能長24個字符,在這種情況下,它將覆蓋舊行和下一行的前4個字符。 為了使這項工作有效,您將不得不在文件后面的行之后“推送”所有內容,而這對於C ++(或C)IO設備是不可能的。
一種選擇是將所有具有固定長度的行(例如50個字符)寫入,以便覆蓋第三行涉及將字符替換為100到149,即使該行實際上只需要24個字符也是如此。
另一種選擇是將文件以基於記錄的形式保存在內存中,並在每次更改時寫出整個文件(或至少寫出新行及其后的所有行)
好的,我設法解決了這個問題,現在它的工作非常出色! :D
首先,該function
檢查播放器名稱是否已經在txt
。 我創建了一個啟用變量j
。 當j=1
,名稱存在並且數據需要被overwritten
! 當j=0
,函數將立即append
數據append
到txt。
好的,假設j=1
。 該函數確定txt
的行數。 然后創建一個vector
里面兩個向量:該name
,以及game variables
。 之后,該函數刪除txt
文件的先前內容。 並將向量的內容寫入txt
,但需要覆蓋的數據除外(它將跳過將該部分寫入txt
),因為在函數結束時,將寫入新數據。 :DI希望我讓自己說得足夠清楚。 抱歉,如果有人聽不懂我寫的話...
這是我新的save_game
函數:
// SAVE GAME
void save_game(Player player)
{
ofstream coutfile (SaveDestiny, ios::app);
if (coutfile.is_open()) // if it opens correctly
{
string imported_name;
ifstream cinfile (SaveDestiny); // opens file that contains the saved games
bool j = 0;
// Now checking if the name already exists
while (cinfile >> imported_name) // while the end of file is not reached
{
if (player.name.compare(imported_name) == 0) // if the strings are the same, overwrite data
{
j = 1; // enable overwrite
break;
}
// if the strings are different, keep reading
}
// at this point: j = 0 to append to end. j = 1 to overwrite.
// Overwriting data
if (j == 1)
{
ifstream cinfile (SaveDestiny);
// now determining the size of the vector (number of lines in txt)
int line_numbers = 0;
string line;
while (getline(cinfile, line))
{
line_numbers++;
}
cinfile.close(); // closing
ifstream cinfile2 (SaveDestiny); // reopening to read from the beginning
// now creating the vector with the saves
vector<vector<string>> temp_saves(line_numbers, vector<string>(2));
string name2;
string values;
for (unsigned int x = 0; x < temp_saves.size(); x++)
{
cinfile2 >> name2;
getline(cinfile2, values);
temp_saves[x][0] = name2;
temp_saves[x][1] = values;
}
coutfile.close(); // closing output file
ofstream coutfile2 (SaveDestiny); // reopening in overwrite mode
// delete all saves.txt, copying vector content to txt (except the one we want to overwrite)
for (unsigned int x = 0; x < temp_saves.size(); x++)
{
if ( temp_saves[x][0].compare(player.name) != 0)
{
coutfile2 << temp_saves[x][0] << temp_saves[x][1] << endl;
}
}
coutfile2.close(); // closing output file
}
// Appending new data...
ofstream coutfile3 (SaveDestiny, ios::app); // reopening in append mode
coutfile3 << player.name << " " << player.level << " " << player.exp << " " << player.max_exp << " "
<< player.hp << " " << player.max_hp << " " << player.mp << " " << player.max_mp << " "
<< player.gold << " " << player.weapon << " " << player.shield << " " << player.heal_spell << " "
<< player.attack_spell << endl;
}
else
{
ofstream coutfile (SaveDestiny, ios::app);
cout << "Unable to open file";
cin.get();
}
draw_rectangle(37,8,72,14,15); // white limits
draw_rectangle(39,9,70,13,9); // blue background
cor(9,15);
gotoxy(50,10);
cout << "GAME SAVED!";
gotoxy(41,12);
cor(9,14);
cout << "Press <Enter> to continue... ";
cin.get();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.