So here is the problem. I have a file that starts with a number, this number says how many entries are in the file (5 means there are 5 names). Each entry takes up two lines in the txt file. First line is the name, the second is a group of four "grades". I get all of this to work great, but I don't understand this: When entering the filename hwk9.txt into the program, I get an empty first spot in the names array. Any other name I have tried works perfectly. I have tried compiling in Bloodshed and the course's online complier as well, no dice.

So the question I am wondering about is this, given multiple files with the same formatting, what would cause the one file (that happens to be the same name as the test file for the assignment that cannot be altered) to give a different result? How does the file "hwk9.txt" give a blank value to namesArray[0] but none of the others do? See lines 38-72 for the code relevant to this.

/*****************************************
 * Computer Science 221
 * Kevin Burdette
 * Date: 11/28/2009
 * Instructor: Dr. Otha Britton
 * This program analyzes input data to return averages
 *****************************************/

#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;

void loadFileToArray (string namesArray[], double gradesArray[][4], int &numberOfStudents);
void displayNamesAndGrades (string namesArray[], double gradesArray[][4], int numberOfStudents);
void calculateAveExamGradeAndDisplay(double grades[][4], int numberOfStudents);

int main ( )
{
    string names[30];
    double grades[30][4];
    int numberOfStudents;
    
    loadFileToArray (names, grades, numberOfStudents);
    displayNamesAndGrades (names, grades, numberOfStudents);
    calculateAveExamGradeAndDisplay (grades, numberOfStudents);
    
    system("pause");
    return 0;
}//end of main

void loadFileToArray (string namesArray[], double gradesArray[][4], int &numberOfStudents)
{
     string filename;
	 ifstream input;
     
     cout << "What is the name of the file to open and analyze?" << endl;
     cin >> filename;
     
     input.open(filename.c_str());
     if (input.fail())
     {
  	    cout << filename << " was not found." << endl;
  	    cout << "Terminating the program . . . ." << endl; //Closes the function if the file does not open properly.
  	    system("pause");
  	    exit(99);
     }//end of fail close statement
     
     input >> numberOfStudents;
     
     while(!input.eof())//continue until end of file
     {
         char junk;
         
         for (int row = 0; row < numberOfStudents ; row++ )
		 {
	 	     input.get(junk); //Gets rid of the new line character
   			 
			 getline( input, namesArray[row]);
		  	 
		  	 for( int col = 0; col < 4 ; col++)
         	 {
			  	  input >> gradesArray[row][col];
		  	 
			 }//end of inner for loop
	     }//end of input for loop
     }//end of while
     input.close();

     return;
}//end of loadFileToArray

void displayNamesAndGrades (string namesArray[], double gradesArray[][4], int numberOfStudents)
{
 	 char letterGrade;
 	 double average;
 	 double sum;
 	  	 
	 cout << setw(30) << left << "Names" << right << setw(10) << "Ave. Score"
	 	  << setw(10) << "Grade" << endl;
     cout << "--------------------------------------------------" << endl;

 	 for (int row = 0; row < numberOfStudents; row++)
 	 {
	  	 sum = 0;
	  	 for (int col = 0; col < 4; col++)
	  	 {
		  	 sum += gradesArray[row][col];
		 }
   		 
		 average = (sum / 4);
		 
		 if (average >= 90)
	  	 	letterGrade = 'A';
	     else if (average >= 80 && average < 90)
	        letterGrade = 'B';
    	 else if (average >= 70 && average < 80)
	        letterGrade = 'C';
	     else if (average >= 60 && average < 70)
	        letterGrade = 'D';
	     else
	        letterGrade = 'F';
	 
	 cout << setprecision(2) << showpoint << fixed;
     cout << setw(30) << left << namesArray[row] << setw(10) << right << average
	 	  << setw(10) << letterGrade << endl;
	 }
     return;
}//end of grades

void calculateAveExamGradeAndDisplay(double grades[][4], int numberOfStudents)
{
    double sumC0, sumC1, sumC2, sumC3;
    sumC0 = 0;
    sumC1 = 0;
    sumC2 = 0;
    sumC3 = 0;
    
    for (int row=0; row < numberOfStudents; row++)
    {
        sumC0 += grades[row][0];
        sumC1 += grades[row][1];
        sumC2 += grades[row][2];
        sumC3 += grades[row][3];
    }
    cout << endl;
	cout << "The average of exam 1 is " << sumC0 / numberOfStudents << endl;
    cout << "The average of exam 2 is " << sumC1 / numberOfStudents << endl;
    cout << "The average of exam 3 is " << sumC2 / numberOfStudents << endl;
    cout << "The average of exam 4 is " << sumC3 / numberOfStudents << endl;
}

Edited 7 Years Ago by hit25: n/a

You've got nested loop issues.
After you get the line, the line is got. Reading "the rest of the line" will be problematic.
You should check for success when you attempt to read from the file.
Avoid using eof() as a loop control.

Edited 7 Years Ago by Dave Sinkula: n/a

Okay, I changed the loadFileToArray function to the code below, eliminating the eof control. I replaced it with a bool that is changed if there is ever a fail state, it is checked everytime through the loop. But I still get the problem of namesArray[0] being empty, and only when using the filename "hwk9.txt". I am at a complete loss as to how this is happening.

I basically adapted another program where I needed a bool return type to determine if the file loaded correctly. I just didn't return the bool.

void loadFileToArray (string namesArray[], double gradesArray[][4], int &numberOfStudents)
{
     string filename;
     bool success = true;
     ifstream inputDataStream;
	 	      
     cout << "What is the name of the file to open and analyze?" << endl;
     cin >> filename;
	 
     inputDataStream.open(filename.c_str());//Actual filename must be C-string
     if(inputDataStream.fail())
          success = false;       //Check for proper file opening.
     
     inputDataStream >> numberOfStudents;   //Primer read
     while( success )
     {   //continue until end of file or until data error
     
         char junk;
         
         for (int row = 0; row < numberOfStudents ; row++ )
		 {
	 	     inputDataStream.get(junk); //Gets rid of the new line character
   			 
			 getline( inputDataStream, namesArray[row]);
		  	 
		  	 for( int col = 0; col < 4 ; col++)
         	 {
			  	  inputDataStream >> gradesArray[row][col];
		  	 
			 }//end of inner for loop
	     }//end of input for loop
	     if(inputDataStream.fail())
            success = false;
     }// end of while
     
     if(inputDataStream.eof())
         success = true;
     return;
}//end of loadFileToArray

Edited 7 Years Ago by hit25: n/a

Okay, I changed the loadFileToArray function to the code below, eliminating the eof control. I replaced it with a bool that is changed if there is ever a fail state, it is checked everytime through the loop. But I still get the problem of namesArray[0] being empty, and only when using the filename "hwk9.txt". I am at a complete loss as to how this is happening.

I don't have this file or some other one that apparently works for you. From what I was tinkering with, I would be surprised with it having ever worked correctly. And since I haven't seen the input file that does work, I can't see that I'm being proven wrong yet. Could you post these input files?

i don't have this file or some other one that apparently works for you. From what i was tinkering with, i would be surprised with it having ever worked correctly. And since i haven't seen the input file that does work, i can't see that i'm being proven wrong yet. Could you post these input files?
HWK1.txt

HWK9.txt

HWK9a.txt

Attachments
8
Doug
95 90 85 100
Chris
25 20 15 10
Bobby
50 85 60 65
Heather
99.69 98.69 95.69 96.69
Kevin
100 100 100 100
Cliff
99 99 99 99
John
40 50 40 31
Ben
1 2 3 4
5
Kevin
100 100 100 100
Doug
95 90 85 100
Chris
25 20 15 10
Bobby
50 85 60 65
Heather
99.69 98.69 95.69 96.69
6
Doug
95 90 85 100
Chris
25 20 15 10
Bobby
50 85 60 65
Heather
99.69 98.69 95.69 96.69
Kevin
100 100 100 100
Cliff
99 99 99 99

Ah! Separate lines for the names and the grades! I stand corrected. My crystal ball file looked like this:

5
foo 95 84 72 87
bar 91 77 82 63
baz 75 63 66 42
qux 50 49 33 58
moo 92 95 97 91
noo 67 81 58 61

Lemme take a look...
[edit]Here's what I see:

What is the name of the file to open and analyze?
hwk9a.txt
Names                         Ave. Score     Grade
--------------------------------------------------
Doug                               92.50         A
Chris                              17.50         F
Bobby                              65.00         D
Heather                            97.69         A
Kevin                             100.00         A
Cliff                              99.00         A

The average of exam 1 is 78.11
The average of exam 2 is 82.11
The average of exam 3 is 75.78
The average of exam 4 is 78.45
Press any key to continue . . . 


What is the name of the file to open and analyze?
hwk9.txt
Names                         Ave. Score     Grade
--------------------------------------------------
                                  100.00         A
Doug                               92.50         A
Chris                              17.50         F
Bobby                              65.00         D
Heather                            97.69         A

The average of exam 1 is 73.94
The average of exam 2 is 78.74
The average of exam 3 is 71.14
The average of exam 4 is 74.34
Press any key to continue . . . 


What is the name of the file to open and analyze?
hwk1.txt
Names                         Ave. Score     Grade
--------------------------------------------------
Doug                               92.50         A
Chris                              17.50         F
Bobby                              65.00         D
Heather                            97.69         A
Kevin                             100.00         A
Cliff                              99.00         A
John                               40.25         F
Ben                                 2.50         F

The average of exam 1 is 63.71
The average of exam 2 is 68.09
The average of exam 3 is 62.21
The average of exam 4 is 63.21
Press any key to continue . . .

Hmm...

Edited 7 Years Ago by Dave Sinkula: n/a

This is exactly what i was getting... how does this only happen on the "hwk9.txt" file?

As seen on line 23, the name is missing!

My assistance has been subpar tonight. Try this:

void loadFileToArray (string namesArray[], double gradesArray[][4], int &numberOfStudents)
{
   string filename;
   ifstream inputDataStream;

   cout << "What is the name of the file to open and analyze?" << endl;
   cin >> filename;

   inputDataStream.open(filename.c_str());//Actual filename must be C-string

   if ( inputDataStream )
   {
      inputDataStream >> numberOfStudents;   //Primer read

      char junk;
      for ( int row = 0; row < numberOfStudents ; row++ )
      {
         inputDataStream.get(junk); //Gets rid of the new line character

         getline( inputDataStream, namesArray[row]);

         for ( int col = 0; col < 4 ; col++ )
         {
            inputDataStream >> gradesArray[row][col];
         }
      }
   }
}

I also added an else statement at the end of the if statement in this code it works perfectly now! Thanks for all the help!

void loadFileToArray (string namesArray[], double gradesArray[][4], int &numberOfStudents)
{
 	 string filename;// for the c_str()
 	 ifstream inputDataStream;// names input file stream
	 
	 cout << "What is the name of the file to open and analyze?" << endl;// prompts user for input of the filename
	 cin >> filename;//saves the input under filename
	 cout << endl;//to clean up the output
	 
	 inputDataStream.open(filename.c_str());//opens the filename (must be C-string)
	 
	 if ( inputDataStream )
	 {
	  	  char junk;//for the extraneous line return character
		  inputDataStream >> numberOfStudents;//reads the first value of the number of students
		  
		  for ( int row = 0; row < numberOfStudents ; row++ )
		  {
		   	  inputDataStream.get(junk); //Gets rid of the new line character
		   	  getline( inputDataStream, namesArray[row]);//inputs the names value
		   	  
		   	  for ( int col = 0; col < 4 ; col++ )//inside loop to handle the 4 grades
		   	  {
			   	  inputDataStream >> gradesArray[row][col];//inputs the grades values
		   	  }//end of grades for loop
 	      }//end of names for loop
    }//end of if statement
    else
    {
              cout << "The file \"" << filename << "\" was not found or failed to open." << endl;
              cout << "Terminating program. . . ." << endl;
              system("pause");
              exit(99);//exits the program if the ifstream enters a fail state
    }//end of else statement
}//end of loadFileToArray
This question has already been answered. Start a new discussion instead.