C++:从文件中读取字符串和整数,并获得最大数字

C++: Read strings and integers from file, and obtain highest number

本文关键字:数字 整数 文件 字符串 读取 C++      更新时间:2023-10-16

我编写了下面的代码,试图从文本文件中读取字符串和整数,其中整数是最高数字(分数(及其相应的字符串(播放器(。我可以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 bestplayerstring currentplayerint 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 ofscoresFile.open("scores.txt"(;. Also, there is no need to callscoresFile.close((' 因为析构函数会处理这个问题。

如果您只想说'n'(或"...n"(,请不要使用std::endlstd::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 << ""!nn";
return EXIT_FAILURE;
}
std::cout << "File opened successfully, program will continue...nn";
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 << "nn";
}

除了重载<<运算符之外,您还可以采取更多的程序方法,简单地检查读取的行中的第一个字符是否是数字,如果是,则转换为带有std::stoiint,并与当前的最大分数进行比较,如果它更大,则更新。

您的数据文件布局有点奇怪,但假设它是您必须使用的,您可以简单地将第一行作为名字读取,并将名称存储为读取循环末尾的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

仔细查看,如果您有其他问题,请告诉我。