簡體   English   中英

C++:從文件中讀取字符串和整數,並獲得最高數字

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

我編寫了下面的代碼,試圖從文本文件中讀取字符串和整數,其中整數是與其對應的字符串(玩家)的最高數字(分數)。 我能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 每次閱讀一行時,我都會增加一個整數。 然后,您取其相對於 2 ( i % 2 ) 的模數,如果它是奇數,則將流輸出到currentplayer 如果是偶數,則將流輸出為臨時整數並將其與bestscore進行比較。 如果它高於bestscore ,設定的值bestscore於整數和集bestplayer = currentplayer 祝你好運!

非必要時不要使用exit() exit()不會做任何堆棧展開和規避 RAII 的原則。 main()您可以輕松使用return EXIT_FAILURE; 在出現錯誤時結束程序。

談論 RAII:使用構造函數為class賦值,例如。 使用std::ifstream scoresFile{ "scores.txt" }; instead of std::ifstream scoresFile{ "scores.txt" }; instead of scoresFile.open("scores.txt"); . Also, there is no need to call . Also, there is no need to call scoreFile.close()`,因為析構函數會處理它。

如果您只想說'\\n' (或"...\\n" ),請不要使用std::endl 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";
}

除了重載<<運算符之外,您還可以采用更多的程序方法,只需檢查讀取的行中的第一個字符是否為數字,如果是,則使用std::stoi轉換為int並與當前的最大值進行比較分數,如果更大則更新。

您的數據文件布局有點奇怪,但假設它是您必須使用的,您可以簡單地將第一行讀取為名字,並在讀取循環結束時將名稱存儲為 say 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

仔細檢查一下,如果您還有其他問題,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM