Extract and manipulate data

I am working on a program that takes info from a text file and manipulates the info to display the qb rating for quarterbacks. The file looks a bit like this:

1
2
3
Nick Foles           PHI 124 196 1791 19 0
Peyton Manning       DEN 305 445 3722 36 7 
Aaron Rodgers        GB  168 251 2218 15 4


Currently, with my code, I am not able to get the first line of my file without initializing it outside of my while loop. Is there a way to get around this? Also, after I have displayed my qbrating data, I need to be able to find the average of the numbers and sort them in descending order. Can someone help me please?

Here is my current code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath> 
using namespace std;

string filename, line;
char teamABV[4], fullName[21];
float completions, attempts, yards, touchdowns, interceptions,
     compPercent, ypAttempt, tdpAttempt, ipAttempt, qbRating;


int main()
{
    cout << "This program will calculate the average passer rating based " << endl;
    cout << "on data from a text file." << endl;
    
    cout << "Please enter your full file's path." << endl;
    cin >> filename;//Get file name for user input
    
    ifstream qbinfo;
    qbinfo.open(filename.c_str());//Open input file
    
    while (qbinfo.fail())//In case of error
    {
        cout << filename << " is an incorrect input. " << endl;
        cout << "Please reenter your full file name and path." << endl;//Re-do
        cin >> filename;
        qbinfo.open(filename.c_str());
        
    }//end while         


            qbinfo.get(fullName, 21);
            qbinfo >> ws;
            qbinfo.get(teamABV, 4);
            qbinfo >> completions >> attempts >> yards >> touchdowns >> interceptions;
           cout << fullName << endl;
           /*cout << teamABV << endl;
           cout << completions << endl; 
           cout << attempts << endl; 
           cout << yards << endl; 
           cout << touchdowns << endl; 
           cout << interceptions << endl;*/// get first player's info
               
                compPercent = ((completions / attempts) * 100 - 30)/20;
                //cout << compPercent << endl;//get completion percent for initializer
                    if (compPercent > 2.375)
                        compPercent = 2.375;
                    else if (compPercent < 0)
                        compPercent = 0;
                    
                ypAttempt = ((yards/ attempts) - 3 ) * 1/4;
                //cout << ypAttempt << endl;//get yards per attempt for initializer
                    if (ypAttempt > 2.375)
                        ypAttempt = 2.375;
                    else if (ypAttempt < 0)
                        ypAttempt = 0;
                
                tdpAttempt = (touchdowns / attempts) * 20;
                //cout << tdpAttempt << endl;//get touchdowns per attempt for initializer
                    if (tdpAttempt > 2.375)
                        tdpAttempt = 2.375;
                    else if (tdpAttempt < 0)
                        tdpAttempt = 0;
                
                ipAttempt = 2.375 - ((interceptions / attempts ) * 25);
                //cout << ipAttempt << endl;//get interceptions per atempt for initializer    
                    if (ipAttempt > 2.375)
                        ipAttempt = 2.375;
                    else if (ipAttempt < 0)
                        ipAttempt = 0;
                        
                qbRating = ((compPercent + ypAttempt + tdpAttempt + ipAttempt) / 6 ) * 100;
                cout << qbRating << endl; // output qb rating and name for initializer
                        
                
                
   while (getline(qbinfo, line))
        {
            qbinfo.get(fullName, 21);
            qbinfo >> ws;
            qbinfo.get(teamABV, 4);
            qbinfo >> completions >> attempts >> yards >> touchdowns >> interceptions;
            qbinfo >> ws;
           cout << fullName << endl;
           /* cout << teamABV << endl;
           cout << completions << endl; 
           cout << attempts << endl; 
           cout << yards << endl; 
           cout << touchdowns << endl; 
           cout << interceptions << endl;*///loop info through rest of file
           compPercent = ((completions / attempts) * 100 - 30)/20;
                //cout << compPercent << endl;//get completion percent for loop
                    if (compPercent > 2.375)
                        compPercent = 2.375;
                    else if (compPercent < 0)
                        compPercent = 0;
                    
                ypAttempt = ((yards/ attempts) - 3 ) * 1/4;
                //cout << ypAttempt << endl;//get yards per attempt for loop
                    if (ypAttempt > 2.375)
                        ypAttempt = 2.375;
                    else if (ypAttempt < 0)
                        ypAttempt = 0;
                
                tdpAttempt = (touchdowns / attempts) * 20;
                //cout << tdpAttempt << endl;//get touchdowns per attempt for loop
                    if (tdpAttempt > 2.375)
                        tdpAttempt = 2.375;
                    else if (tdpAttempt < 0)
                        tdpAttempt = 0;
                
                ipAttempt = 2.375 - ((interceptions / attempts ) * 25);
                //cout << ipAttempt << endl;//get interceptions per attempt for loop
                    if (ipAttempt > 2.375)
                        ipAttempt = 2.375;
                    else if (ipAttempt < 0)
                        ipAttempt = 0;
                
                qbRating = ((compPercent + ypAttempt + tdpAttempt + ipAttempt) / 6 ) * 100;
                cout << qbRating << endl;//output qb rating and name for loop
        }//end while()
        
        
    qbinfo.close();
    system("pause");
    
}


I must note here that in order for my program to be successful, I MUST extract the data by using the first 20 columns for fullName, then the next 4 for teamABV, and the rest are separated in order by white space.
I MUST extract the data by using the first 20 columns for fullName, then the next 4 for teamABV

The example data presented above sort of conforms to that specification, but like this:

         1    1    2    2    3    3    4    4    5
12345678901234567890123456789012345678901234567890
Nick Foles           PHI 124 196 1791 19 0
Peyton Manning       DEN 305 445 3722 36 7 
Aaron Rodgers        GB  168 251 2218 15 4

Either there is a blank space in column 21, or the teamABV starts with a leading space, like this: " PHI"

But for now I'll assume that column 21 is a space, to be ignored.

Since you are using getline(), which is a reasonable approach, you could use a stringstream to parse the contents of the line, something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    string filename, line;
    
    filename = "input.txt";

    char teamABV[5], fullName[21];
    float completions, attempts, yards, touchdowns, interceptions;

    ifstream qbinfo(filename.c_str());

    while (getline(qbinfo, line))
    {
        istringstream ss(line);

        ss.get(fullName, 21);
        ss.ignore();
        ss.get(teamABV, 5);
        ss >> completions >> attempts >> yards >> touchdowns >> interceptions;

        cout << fullName << endl;
        cout << teamABV << endl;
        cout << completions   << " "
             << attempts      << " "
             << yards         << " "
             << touchdowns    << " "
             << interceptions << endl;

    }


I've omitted the code where the values are used after reading them.

Regarding the requirement to "to find the average of the numbers and sort them in descending order", you will need to store the data in an array or vector so that it can be sorted. One approach is to define a struct to hold all of the data for a single player, and then have an array of those objects.
Last edited on
Is there a different approach besides getline()? I very much appreciate your response, you are quite helpful. Unfortunately, this is for a project in my programming class, so my instructor may not be willing to take my code if I use string streams, as we haven't covered them yet. Would there be a way to extract my data into an array using a for loop?

Also, regarding the text file, it seems that I mistakenly put an extra space in my sample file. I have since fixed this.
You might try something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    while ( qbinfo.get(fullName, 21)
        &&  qbinfo.get(teamABV, 5)
        && (qbinfo >> completions >> attempts >> yards >> touchdowns >> interceptions))
    {
        qbinfo.ignore(1000, '\n');  // get rid of the trailing newline.
        cout << fullName << endl;
        cout << teamABV << endl;
        cout << completions   << " "
             << attempts      << " "
             << yards         << " "
             << touchdowns    << " "
             << interceptions << endl;

    }


It's by no means the only approach, but there are advantages to doing all of the input for a line as part of the while condition, mainly it ensures that the body of the loop is entered only when the data was successfully read from the file. Notice at line 5 the use of ignore() to ensure that the '\n' character at the end of each line is read and discarded.
Thank you for all of your help. You really saved my butt. Now, as for reading the data into an array, is there a way to store this information into an array after it has been read, or will I need to manipulate the code to read it into an array first?
You could do it either way. It might be argued that one way might be slightly faster or more efficient than another, but I'd not be concerned about that aspect here.
Sorry to bug you again, but now I am have trouble storing the names and ratings into parallel arrays. For that matter, when I try to store fullName into a string, it will not accept it because it is a char. Is there a way to convert this? I am sorry I keep adding questions but I am not too familiar with the logic about arrays and I'm driving myself nuts trying to finish this program tonight.
when I try to store fullName into a string, it will not accept it because it is a char

Please show the actual code which is giving you problems.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath> 
using namespace std;

char teamABV[4], fullName[21];
int nameArray[50];
int i = 0;

                while ( qbinfo.get(fullName, 21)
                &&  qbinfo.get(teamABV, 4)
                && (qbinfo >> completions >> attempts >> yards >> touchdowns >> interceptions))
             {
                    qbinfo.ignore(1000, '\n');

                    nameArray[i] = fullName;
                    i++;
             }//end while()


I'm sorry if this is messy, but I tried to omit everything except what we're dealing with. I get an invalid conversion from char to int.
I tried using char* but when I do, it would only display single characters of the array, while I need to be able to access the full 21 characters we are dealing with.
Thanks, the problem is clearer now.
Probably the simplest solution is to change this array:
 
int nameArray[50];
to
 
string nameArray[50];

After that, the line nameArray[i] = fullName; should work with no problems.
Topic archived. No new replies allowed.