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

时间:2018-09-22 05:37:07

标签: c++

我写了下面的代码,试图从文本文件中读取字符串和整数,其中整数是最高数字(分数)及其相应的字符串(玩家)。我可以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;
}

3 个答案:

答案 0 :(得分:0)

设置变量string bestplayerstring currentplayerint bestscore = 0。每当您读一行时,我都会增加一个整数。然后,取它相对于两个(i % 2)的模数,如果它是奇数,则将流输出到currentplayer。如果是偶数,则将流输出为一个临时整数并将其与bestscore进行比较。如果它大于bestscore,则将bestscore的值设置为该整数并设置bestplayer = currentplayer。祝你好运!

答案 1 :(得分:0)

当您并非绝对不必使用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";
}

答案 2 :(得分:0)

除了重载<<运算符之外,您还可以采取更多的程序方法,只需检查读取的行中的第一个字符是否为数字,然后将其转换为int std::stoi并与您当前的最高得分进行比较,如果得分更高,则进行更新。

您的数据文件布局有点奇怪,但是假设它是您要使用的格式,您可以简单地将第一行读取为名字,然后将名称存储为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

仔细检查一下,如果还有其他问题,请告诉我。