I'm writing a program that is supposed to be able to bubble sort data by name and by average. The data I'm given is student last name followed by 3 scores, all put into a text document. I'm to read the names and scores into their respective parallel arrays, and get the averages of the scores for each student put into a 3rd and final array. Looks like this:

Lastname 90 91 92
Lastname 80 81 82

This is the code I have for the read function:

int read(char filename[], char names[][30], int scores[][3], double averages[])
{
    int sum = 0;                        // the base of finding the average
    int numStu = 0;                     // how many students we will have
    int col = 0;                        // column for names
    // read text document
    ifstream infile(filename);      // define
    infile.open(filename);          // open
    
    for (int i = 0; i < 100; i++)
    {
        infile.getline(names[i], 30, ' ');  // get the name, stop when white space is found
        if (! names == 'z')             // no names start with lowercase 'z'
        {
            for (int j = 0; j < 4; j++)
            {
                infile >> scores[i][j]; // start plugging in scores
                sum += scores[i][j];    // while we're at it, get the sum of the scores
            }
            averages[i] = sum / 3.0;    // get the average for this name    
        }
        
        numStu = i;
    }
    infile.close();         // close
    
    return numStu;
}

This is the code for my write function (outfile stuff in comments because I'm trying to make this work with screen output first):

void write(char filename[], ios::openmode, char description[], char names[][30], int scores[][3], double averages[], int numberOfStud)
{
    // write to text file
    // ofstream outfile(filename, mode); // define
    cout << description << endl;
    
    for (int i = 0; i < numberOfStud; i++)
    {
        cout << names[i] << ' ';         // print the name
        cout << fixed << setw(7) << setprecision(2) << averages[i] << ' ';
                                         // then the averages
        for (int j = 0; j < 4; j++)
        {
            cout << scores[i][j] << ' '; // then the three exam scores
        }
        cout << endl;   // then go to the next line
    }
    
    // outfile.close();
}

I'm having a problem with garbage output. It comes up with long lines of irrational numbers, intersparsed with many 0's. I'm not sure what I'm missing here. I think the problem is located in the read function.

line 7 and 8 of the read function: Line 8 is unnecessary because line 7 opens the file when the stream is declared.

line 12: if lastname never contains spaces then use use >> operator instead of getline().

line 13: doesn't make any sense. names is an array, but you are treating it as a simple string. And it is more common to use the != operator rather than ! and == as you have done. if( names[i] != "z") line 15: you are reading in 4 scores, but the array can only hold 3.

line 20: Where is sum initialized to 0? It needs to be done just before the loop starts on line 15.

line 7 and 8 of the read function: Line 8 is unnecessary because line 7 opens the file when the stream is declared.

line 12: if lastname never contains spaces then use use >> operator instead of getline().

line 13: doesn't make any sense. names is an array, but you are treating it as a simple string. And it is more common to use the != operator rather than ! and == as you have done. if( names[i] != "z") line 15: you are reading in 4 scores, but the array can only hold 3.

line 20: Where is sum initialized to 0? It needs to be done just before the loop starts on line 15.

The changes you mentioned have been made except for changing ! == to !=. For some reason, my compiler is not liking !=. I get the error "ISO C++ forbids comparison between pointer & integer". I'm using Cygwin, if that helps.

Some of the other things you mentioned, I felt silly for not having done. I chalk it up to being tired and stressed, careless mistakes.

I'm still getting the same problem though changes have been made.

Code now:

int read(char filename[], char names[][30], int scores[][3], double averages[])
{
    int sum;
    int numStu = 0;                     // how many students we will have
    int col = 0;                        // column for names
    // read text document
    ifstream infile(filename);      // define & open
    
    for (int i = 0; i < 100; i++)
    {
        infile >> names[i];              // get the name
        if (! names[i] == 'z')             // no names start with lowercase 'z'
        {
            sum = 0;                     // base finding of the average
            for (int j = 0; j < 3; j++)
            {
                infile >> scores[i][j]; // start plugging in scores
                sum += scores[i][j];    // while we're at it, get the sum of the scores
            }
            averages[i] = sum / 3.0;    // get the average for this name    
        }
        
        numStu = i;
    }
    infile.close();         // close
    
    return numStu;
}

>>The changes you mentioned have been made except for changing ! == to !=. For some reason, my compiler is not liking !=. I get the error "ISO C++ forbids comparison between pointer & integer". I'm using Cygwin, if that helps.


Your compiler is correct -- I was thinking names was an array of std::string, not characters. use strcmp() instead if( strcmp(names[i], "z") != 0)

>>The changes you mentioned have been made except for changing ! == to !=. For some reason, my compiler is not liking !=. I get the error "ISO C++ forbids comparison between pointer & integer". I'm using Cygwin, if that helps.


Your compiler is correct -- I was thinking names was an array of std::string, not characters. use strcmp() instead if( strcmp(names[i], "z") != 0)

I have made that change to the if statement, still getting garbage when I try to write what's in the arrays. =/

I have made that change to the if statement, still getting garbage when I try to write what's in the arrays. =/

Actually, using the string compare helped out quite a bit. In my newbness, I guess I ignored the fact that strings are dealt with differently than number arrays.

In case this helps anyone else, here is the final product for the read function:

int read(char filename[], char names[][30], int scores[][3], double averages[])
{
    // initialize names array to blank
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            names[i][j] = ' ';
        }
    }
    // initialize scores & averages to 0
    for (int i = 0; i < 10; i++)
    {
        averages[i] = 0;
        for (int j = 0; j < 3; j++)
        {
            scores[i][j] = 0;
        }
    }
    
    int sum;
    int numStu = 0;                     // how many students we will have
    int col = 0;                        // column for names
    // read text document
    ifstream infile(filename);      // define & open
    
    for (int i = 0; i < 10; i++)
    {
        infile >> names[i];              // get the name
        sum = 0;                     // base finding of the average
        if (strcmp(names[i], "zzz") != 0)
        {
            for (int j = 0; j < 3; j++)
            {
                infile >> scores[i][j]; // start plugging in scores
                sum += scores[i][j];    // while we're at it, get the sum of the scores
            }
            averages[i] = sum / 3.0;    // get the average for this name            
            numStu = i;   
        }
    }
    infile.close();         // close
    
    return numStu;
}

You might as well delete the loops on lines 4-10 because that initialization is just undone (destroyed) by line 29.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.