简体   繁体   中英

C++ Read .txt file columns into an array

Hello all I am not new to C++ but my skills are not very honed. Anyways I have an assignment that I was not able to complete on time, and it is really bugging me that I could not get my code to work. Now I just want to finish it so that I may know how for a future assignment.

The data file contains the number of players and their scores on the same line and the last column is their time.

The question is this, there is a .txt file that I must open in my program that reads as this(without bullet points).

  • 27
  • pop 23 45 92 34 43 125
  • cop 4 23 56 23 75 323
  • ... and so forth.

How can I store/ignore the first variable and then make arrays with the data column by column (Seperated by white space)?

Here is what I have created. I have created the arrays that I need to store the respective data into.

#include <iostream>
#include <cmath>
#include <ctime>
#include <iomanip>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;

int main()
{
    cout<<"Welcome to the Score Sorting Program! \n";
    cout<<"Please choose a number that corresponds with the way you would like to  sort. \n";
    cout<<"You may also search by player if you know their username. \n";

    string players[50]; //Allocated space for 50 players.
    int score1[27]; //Array for Score 1
    int score2[27]; //
    int score3[27]; //
    int score4[27]; //
    int score5[27]; //
    int time[27];   //Array for Time
    int i = 0;
    int j = 0;

    ifstream myfile;
    myfile.open("G2347M.txt");
    if (!myfile)
    {
         cout<<"Could not open file. \n";
         system ("Pause");
         return -1;
    }  

    while (!myfile.eof())
    {
        getline(myfile, players[i], ' ');
        if (i == 26)
        {
            i=0;
            ++j;
            getline(myfile, players[i],' ');
        }
        i++;
    }    

}

So basically I will then align players with their scores and output to another file. I just want to get this first part of reading the file in and then I will move on.

I have researched similar topics (4 hours +), trying to piece together the code to get mine to work. I will continue to research and update with anything I can.

Why 50 players but only 27 scores?

I assume the first line is the total number of lines you are expecting to read? If so you could dynamically allocate the arrays to hold all the data rather than just handling 50 (or is it 27) lines. You could also combine all the data for one line into a struct instead of spreading it over a bunch of disconnected arrays.

Pseudo code:

int lineNo = 1;
int totalLines = -1; /* not set */

while(line = read_a_line()) {
    if (lineNo == 1) {
        totalLines = convert_line_text_to_number();
    }
    else {
        /* split the line into "tokens" separated by white space */
        /* store each token in the correct array */
    }
    lineNo++;
    /* if lineNo is too big, break the loop */
}

The best way to use it will be use of vectors. but as you told that you are bound to use Arrays so here is the code for it.

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    ifstream file;
    file.open("sample.txt");

    string name[50];
    int score1[27],score2[27],score3[27],score4[27],score5[27],time[27];


    int i = 0;
    while(!file.eof())
    {
        string line;
        getline(file,line);
        char* a = const_cast<char*>(line.c_str());  
        char* pch = strtok (a," ");

        name[i] = pch;
        int counter = 1;
        while (counter < 7)
        {
            pch = strtok (NULL, " ");

            if(counter == 1)
            {
                score1[i] = atoi(pch);
            }
            else if(counter == 2)
            {
                score2[i] = atoi(pch);
            }
            else if(counter == 3)
            {
                score3[i] = atoi(pch);
            }
            else if(counter == 4)
            {
                score4[i] = atoi(pch);
            }
            else if(counter == 5)
            {
                score5[i] = atoi(pch);
            }
            else if(counter == 6)
            {
                time[i] = atoi(pch);
            }

            ++counter;
        }

        ++i;
    }

    //cout<<a;
    return 0;
}

Please let me know if you face any issue. I have not added some basic sanity checks like one for file, please do that in your version of it.

Here's an approach that uses encapsulation and overloading of operator>>. I'm assuming that what you were describing for the input was just a long sequence of space separated input values with the first value being the count of players.

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <ctype.h>

using namespace std;

static const size_t MaxNumPlayers = 50;

// C++ is about encapsulation, and the player data is
// discrete yet related, so encapsulate it.
struct Player
{
    string m_name;
    int m_scores[5];
    size_t GetNumScores() const { return sizeof(m_scores) / sizeof(m_scores[0]); }
    int m_time;
};

// This allows us to write an operator that will read a player
// directly from an ifstream.
std::ifstream& operator>>(ifstream& istr, Player& player)
{
    istr >> player.m_name;
    for(size_t i = 0; i < player.GetNumScores(); ++i)
    {
       istr >> player.m_scores[i];
    }
    istr >> player.m_time;
    cout << "player: " << player.m_name << ", " << player.m_scores[0] << " @ " << player.m_time << endl;
    return istr;
}

int main(int argc, const char** argv)
{
    ifstream myfile("G2347M.txt");
    if (!myfile)
    {
         cout<<"Could not open file. \n";
         system("Pause");
         return -1;
    }

    // We can read the number of players directly.
    size_t numPlayers = 0;
    myfile >> numPlayers;
    if (numPlayers <= 0 || numPlayers > MaxNumPlayers) {
        cout << "Invalid number of players in score file ("<<numPlayers<<")." << endl;
        system("Pause");
        return -1;
    }

    Player players[MaxNumPlayers];
    size_t playersRead = 0;

    while (!myfile.eof())
    {
        myfile >> players[playersRead++];
        if (playersRead >= numPlayers)
            break;
        // drain any spaces after the player.
        while(isspace(myfile.peek()))
          myfile.ignore();
    }

    if (playersRead != numPlayers)
    {
        cout << "Problem reading score file, expected " << numPlayers << " but read " << playersRead << endl;
        system("Pause");
        return -1;
    }

    cout<<"Welcome to the Score Sorting Program! I read "<<playersRead<<" players."<<endl;
    cout<<"Please choose a number that corresponds with the way you would like to sort."<<endl;
    cout<<"You may also search by player if you know their username.\n"<<endl;

    /* ... */

    system("Pause");
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM