我编写了下面的代码,试图从文本文件中读取字符串和整数,其中整数是最大数字(得分)及其对应的字符串(播放器)。我能够cout
文件的内容,但我如何测试哪个数字是最高的,我如何将其链接到其播放器?任何帮助将不胜感激,谢谢!
文本文件的内容:
Ronaldo
10400
Didier
9800
Pele
12300
Kaka
8400
Cristiano
8000
码:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string text;
string player;
int scores;
ifstream scoresFile;
// Open file
scoresFile.open("scores.txt");
// Check if file exists
if (!scoresFile) {
cerr << "Unable to open file: scores.txt" << endl;
exit(0); // Call system to stop
}
else {
cout << "File opened successfully, program will continue..." << endl << endl << endl;
// Loop through the content of the file
while (scoresFile >> text) {
cout << text << endl;
}
}
// Close file
scoresFile.close();
return 0;
}
做一个变量string bestplayer
,string currentplayer
和int bestscore = 0
。每次读一行我都会增加一个整数。然后,你将它的模数相对于两个(i % 2
),如果它是奇数,你将流输出到currentplayer
。如果是偶数,则将流输出为临时整数并将其与bestscore
进行比较。如果它高于bestscore
,则将bestscore
的值设置为该整数并设置bestplayer = currentplayer
。祝你好运!
当你不是必须时,不要使用exit()
。 exit()
不会进行任何堆栈解除并绕过RAII的原则。在main()
中,如果出现错误,您可以轻松使用return EXIT_FAILURE;
结束程序。
谈论RAII:使用构造函数给class
它的值,例如。使用std::ifstream scoresFile{ "scores.txt" }; instead of
scoresFile.open(“scores.txt”); . Also, there is no need to call
scoresFile.close()`因为析构函数会处理它。
如果你想说的只是std::endl
(或'\n'
),请不要使用"...\n"
。 std::endl
不仅会在流中插入换行符('\n'
),还会将其刷新。如果你真的想要刷新流然后显式并写std::flush
而不是std::endl
。
现在到手头的问题。优雅的解决方案是拥有一个代表player
的对象,其中包含玩家名称和分数。这样的对象不仅可以用于读取高分榜,还可以用于游戏过程中。
为了输入和输出,会使流插入和提取操作符过载。
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
class player
{
std::string name;
int score;
friend std::ostream& operator<<(std::ostream &os, player const &p);
friend std::istream& operator>>(std::istream &is, player &p);
public:
bool operator>(player const &other) { return score > other.score; }
};
std::ostream& operator<<(std::ostream &os, player const &p)
{
os << p.name << '\n' << p.score;
return os;
}
std::istream& operator>>(std::istream &is, player &p)
{
player temp_player;
if (is >> temp_player.name >> temp_player.score)
p = temp_player; // only write to p if extraction was successful.
return is;
}
int main()
{
char const * scoresFileName{ "scores.txt" };
std::ifstream scoresFile{ scoresFileName };
if (!scoresFile) {
std::cerr << "Unable to open file \"" << scoresFileName << "\"!\n\n";
return EXIT_FAILURE;
}
std::cout << "File opened successfully, program will continue...\n\n";
player p;
player highscore_player;
while (scoresFile >> p) { // extract players until the stream fails
if (p > highscore_player) // compare the last extracted player against the previous highscore
highscore_player = p; // and update the highscore if needed
}
std::cout << "Highscore:\n" << highscore_player << "\n\n";
}
除了重载<<
运算符之外,您还可以采用更多的程序方法,只需检查读取行中的第一个字符是否为数字,如果是,则将int
转换为std::stoi
并与当前最大分数进行比较,更新if它更大。
您的数据文件布局有点奇怪,但假设它是您必须使用的,您可以简单地读取第一行作为名字,并在读取循环结束时将名称存储为lastname
,以便它是在下一行读取整数时可用。
利用std::exception
验证std::stoi
转换将确保您在进行比较和更新高分之前处理有效的整数数据,例如
// Loop through the content of the file
while (scoresFile >> text) {
if ('0' <= text[0] && text[0] <= '9') { /* is 1st char digit? */
try { /* try and convert to int */
int tmp = stoi (text);
if (tmp > scores) { /* if tmp is new high score */
scores = tmp; /* assign to scores */
player = lastplayer; /* assign lastplayer to player */
}
} /* handle exception thrown by conversion */
catch ( exception& e) {
cerr << "error: std::stoi - invalid argument or error.\n" <<
e.what() << '\n';
}
}
else /* if 1st char not a digit, assign name to lastplayer */
lastplayer = text;
}
另一个说明。初始化变量以在大于比较中使用时,应将值初始化为INT_MIN
以确保正确处理负值。 (对于小于比较,初始化为INT_MAX
)
完全放在一起,你可以做类似的事情:
#include <iostream>
#include <string>
#include <fstream>
#include <limits>
using namespace std;
int main() {
string text;
string player;
string lastplayer;
int scores = numeric_limits<int>::min(); /* intilize to INT_MIN */
ifstream scoresFile;
// Open file
scoresFile.open("scores.txt");
// Check if file exists
if (!scoresFile) {
cerr << "Unable to open file: scores.txt" << endl;
exit(0); // Call system to stop
}
cout << "File opened successfully, program will continue..." <<
endl << endl;
// Loop through the content of the file
while (scoresFile >> text) {
if ('0' <= text[0] && text[0] <= '9') { /* is 1st char digit? */
try { /* try and convert to int */
int tmp = stoi (text);
if (tmp > scores) { /* if tmp is new high score */
scores = tmp; /* assign to scores */
player = lastplayer; /* assign lastplayer to player */
}
} /* handle exception thrown by conversion */
catch ( exception& e) {
cerr << "error: std::stoi - invalid argument or error.\n" <<
e.what() << '\n';
}
}
else /* if 1st char not a digit, assign name to lastplayer */
lastplayer = text;
}
// Close file
scoresFile.close();
cout << "Highest Player/Score: " << player << "/" << scores << '\n';
return 0;
}
示例使用/输出
$ ./bin/rdnamenum2
File opened successfully, program will continue...
Highest Player/Score: Pele/12300
仔细看看,如果您有其他问题,请告诉我。