How do I replace a line in a txt file with console in c++?
I want to make a high score for a win32 console game. The high score text file will have 10 lines in it for the 10 best people ever played. I've been using examples from http://www.cplusplus.com/doc/tutorial/files/. If you scroll down to text files I've been using those 2 examples together in one project.
Also, Is it possible to make it so that the application will automatically read the file to see if the score is in the top 10? And automatically sort th开发者_Go百科e top ten out from top to bottom from highest to lowest?
i'm using visual c++ express 2010
Get your vector containing the current high scores, add your new one to it, sort based on score, then have a print function which iterates from 0 to 9 in the sorted vector and writes each as a line to a file. Replacing it each time (if it's only 10 lines) isn't that big a deal.
Here's a general outline of what I'd do:
I. Read in the high score file as in the example. Place the values in a vector of classes containing the score and player name. Maybe use a class like:
class MyData
{
public:
int m_iData;
string m_strSomeOtherData;
};
II. Sort the vector. See http://www.codeguru.com/forum/showthread.php?t=366064
III. If the new score is higher than the lowest score in the sorted vector, add it to the vector, re-sort the vector, and write the top 10 scores to the high score file as in the example.
Are the line lengths fixed? If yes, you can seek to the correct position in the file and just write the new line.
If no: Write a new one. You have to read the old one line by line. If the line you just read is the line you want to replace, write the new one to the new file. If it is not, just write the line unchanged to the new file. Delete the old file and rename the new file to the old file's name when you are finished.
Since you only have the one file, and it only contains high score data, I wouldn't worry about speed of file access. This file will be tiny.
Instead, when reading it, just load the whole file, sort it, and truncate all but the top 10 scores. You can do this with:
std::vector<Score> result;
std::fstream file;
file.open(filename, std::ios::in);
std::vector<std::string> lines;
std::string line;
while(std::getline(file, line))
lines.push_back(line);
for(size_t i = 0; i < lines.size(); ++i)
{
const std::string& line(lines[i]);
std::istringstream iss(line);
Score score;
if(!(iss >> score))
throw new std::runtime_error("failed to convert to score: " + line);
result.push_back(score);
}
std::sort(result.begin(), result.end(), isScoreGreater);
if(result.size() > numScoresToKeep)
result.resize(numScoresToKeep);
return result;
When writing it, sort your scores, drop all but the top ten, and overwrite the existing file. You can do this with:
std::fstream file;
file.open(filename, std::ios::out);
std::sort(scores.begin(), scores.end(), isScoreGreater);
if(scores.size() > numScoresToKeep)
scores.resize(numScoresToKeep);
for(size_t i = 0; i < scores.size(); ++i)
file << scores[i] << "\n";
This all assumes you have a class called Score
, input/output stream functions defined against it, and a isScoreGreater
function. When I wrote this up, I used a typedef, and defined the other three functions myself:
typedef std::pair<std::string, unsigned int> Score;
std::istream& operator>>(std::istream& inputStream, Score& score)
{
inputStream >> score.first;
inputStream >> score.second;
return inputStream;
}
std::ostream& operator<<(std::ostream& outputStream, const Score& pair)
{
outputStream << pair.first;
outputStream << " ";
outputStream << pair.second;
return outputStream;
}
bool isScoreGreater(const Score& lhs, const Score& rhs)
{
return lhs.second > rhs.second;
}
But there's nothing keeping you from turning this into a full-fledged class (if you feel like it).
精彩评论