BAD OUTPUT TO TEXT FILE

When i run this program, it doesn't  return the correct information;
the following is a copy of the program, the input file which is named
GRADES.DAT and a copy of the bad information i'm recieving

//  grades.cpp
//  reads a data file and creates a report (text file) from the data file
//   after some processing of the data
//  input file - grades.dat  MUST exist
//  output file - grades.txt is created and overwritten if it exists

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

// prints headings, title to output file fout
void printHeadings(ofstream & fout);

// prints all data to fout in neat format
void printResults(string, int, int, int, double, char, ofstream &);

// calculate average of 3 grades g1 g2 and g3
double calcAverage(int g1, int g2, int g3);

// determine letter grade using av
char calcGrade(double av);

int main()
{
 
  ifstream fin;// file variable for input file
  ofstream fout; // file variable for output file
  fin.open("A:\\GRADES.DAT");
  if (fin.fail())
  {
    cout << "Error opening data file , now exiting " << endl;
    return 1;
  }
  fout.open("A:\\grades.txt");  // file variable for output file
  if (fout.fail())
  {
        cout << "Error opening file for output, now exiting \n";
     return 1;
  }
 
  int grade1, grade2, grade3;  // 3 test grades respectively
  double avg;  // calculated average of 3 test grades
  string name;  // student name
  const string SENTINEL = "zzzz";  // sentinel value on file
  char grade;  // letter grade for average
 
  printHeadings(fout);
  getline(fin,name);
  while (name != "zzzz")
  {
     fin >> grade1 >> grade2 >> grade3;
     fin.ignore(24, '\n');
     avg = calcAverage(grade1, grade2, grade3);
     grade = calcGrade(avg);
     printResults(name, grade1, grade2, grade3, avg, grade, fout);
     getline(fin, name);
  }
  fin.close();
  fout.close();
  return 0;
}
 
void printHeadings(ofstream & fout)
// prints headings, title to output file fout
{

  fout << setiosflags(ios::fixed | ios::showpoint);

  fout << setw(60) << "Grade Report" << endl << endl;
  fout << "Name" << setw(16) << " " << setw(10) << "Grade 1"
       << setw(10) << "Grade 2" << setw(10) << "Grade 3"
       << setw(15) << " Grade Average"
       << setw(10) << " Grade" << endl;
}
void printResults(string nm, int g1, int g2, int g3, double av,
                  char grd, ofstream & fout)
// prints all data to fout in neat format
{
  fout << nm << setw(2-nm.length()) << " " 
       << setw(10) << g1
       << setw(10) << g2 << setw(10) << g3
       << setw(13) << setprecision(1) << av
       << setw(9) << " " << grd << endl;
}
 
double calcAverage(int g1, int g2, int g3)
// calculate average of 3 grades g1 g2 and g3
{
  return double(g1 + g2 + g3) / 3 ;
}

char calcGrade(double av)
// determine letter grade using av
{
 char g; // used to store lettergrade for return value

 if (av >=90.0)
    g = 'A';
 else if (av >= 80.0)
    g = 'B';
 else if (av >= 70.0)
    g = 'C';
 else if (av >=60.0)
    g = 'D';
 else
    g = 'F';
 return g;
}


next is a copy of GRADES.DAT

BD C C B Z
DV B C C Z
JK D A F Z
EL F B C Z
AU F B D Z
AH A A A Z
AB B D C Z
MM A C B Z
KG D C D Z
BW C D D Z
BM D B D Z
RL B B C Z
RC D A B Z
CH C F B Z
LP B D D Z
MT B D C Z
AI C F A Z
AE F C A Z
CB A A A Z
SR D F F Z
SC F A C Z
MG A B D Z
ZZZZ

in the grades.dat file the first 2 character are the students initials
the next 3 are grades the z is supposed to mark the end of the line for that student.

next is the results i'm getting::

                                                Grade Report

Name                   Grade 1   Grade 2   Grade 3  Grade Average     Grade
MB A B A zzzz -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
  -858993460-858993460-858993460  572662305.3         A
 
what did i do wrong?
tbell000Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

meow00Commented:
Hello , I think there are several  problems :
-------------------------------------------------------------------
  int grade1, grade2, grade3;  // 3 test grades respectively
  string G1, G2, G3 ;
  double avg;  // calculated average of 3 test grades
  string name;  // student name
  const string SENTINEL = "zzzz";  // sentinel value on file
  char grade;  // letter grade for average

  printHeadings(fout);
//  getline(fin,name);
//  while (name != "zzzz")
  string temp ;
  while (fin)
  {
     fin >> name >> G1 >> G2 >> G3 >> temp;
  //   fin.ignore(24, '\n');
     map_Grad_to_score() ;
     cout << name << grade1 << "  " << grade2<< "  " << grade3 << endl ;
     avg = calcAverage(grade1, grade2, grade3);
     grade = calcGrade(avg);
     printResults(name, grade1, grade2, grade3, avg, grade, fout);
     getline(fin, name);
  }
----------------------------------
 1. you can directly do "while(fin)", it will stop while reaching the end of the file
 2. in GRADES.DAT, the grades are A, B, C, D ... we can not input them to integer grade1, grade2, grade3 directly calculate. We might need to input them to a string, then mapping them to the integer, i.e. make a function "map_Grad_to_score()", depends on how u want to map it .....

 This is what I think for now ......

meow...
0
PlanetCppCommented:
theres a few problems, first off don't write to the same file youre reading from at the same time your trying to read from it. so i changed that to output to gradesout.dat in the same directory
also you dont need the last name to be "ZZZZ", you just loop until end of file .eof()
you had that lopping until name == "zzzz" which is wrong anyway cause the last name is uppercase not lowercase.
i changed the integer variables to characters, you're using them only as characters then you should use char variables.
other then that it was ok
#include <iomanip>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

// prints headings, title to output file fout
void printHeadings(ofstream & fout);

// prints all data to fout in neat format
void printResults(string, int, int, int, double, char, ofstream &);

// calculate average of 3 grades g1 g2 and g3
double calcAverage(char g1, char g2, char g3);

// determine letter grade using av
char calcGrade(double av);

int main()
{
 
  ifstream fin;// file variable for input file
  ofstream fout; // file variable for output file
  fin.open("c:\\documents and settings\\chris\\desktop\\grades.dat");
  if (fin.fail())
  {
    cout << "Error opening data file , now exiting " << endl;
    return 1;
  }
  fout.open("c:\\documents and settings\\chris\\desktop\\gradesout.dat");  // file variable for output file
  if (fout.fail())
  {
       cout << "Error opening file for output, now exiting \n";
     return 1;
  }

  char grade1, grade2, grade3;  // 3 test grades respectively (CHANGED int to char)
  double avg;  // calculated average of 3 test grades
  string name;  // student name
  const string SENTINEL = "zzzz";  // sentinel value on file
  char grade;  // letter grade for average
 
  printHeadings(fout);
  //getline(fin,name);
  fin>>name;

  while (!fin.eof())//you had this as "zzzz", "zzzz" is not equal to "ZZZZ" caused endless loop
  {
     fin >> grade1 >> grade2 >> grade3;
     //fin.ignore(24, '\n');
     avg = calcAverage(grade1, grade2, grade3);
     grade = calcGrade(avg);
     printResults(name, grade1, grade2, grade3, avg, grade, fout);
     //getline(fin, name);
       fin>>name;
  }
  fin.close();
  fout.close();
  return 0;
}

void printHeadings(ofstream & fout)
// prints headings, title to output file fout
{

  fout << setiosflags(ios::fixed | ios::showpoint);

  fout << setw(60) << "Grade Report" << endl << endl;
  fout << "Name" << setw(16) << " " << setw(10) << "Grade 1"
       << setw(10) << "Grade 2" << setw(10) << "Grade 3"
       << setw(15) << " Grade Average"
       << setw(10) << " Grade" << endl;
}
void printResults(string nm, int g1, int g2, int g3, double av,
                  char grd, ofstream & fout)
// prints all data to fout in neat format
{
  fout << nm << setw(2-nm.length()) << " " 
       << setw(10) << g1
       << setw(10) << g2 << setw(10) << g3
       << setw(13) << setprecision(1) << av
       << setw(9) << " " << grd << endl;
}
 
double calcAverage(char g1, char g2, char g3)//changed parameters to char
// calculate average of 3 grades g1 g2 and g3
{
  return double(g1 + g2 + g3) / 3 ;
}

char calcGrade(double av)
// determine letter grade using av
{
 char g; // used to store lettergrade for return value

 if (av >=90.0)
    g = 'A';
 else if (av >= 80.0)
    g = 'B';
 else if (av >= 70.0)
    g = 'C';
 else if (av >=60.0)
    g = 'D';
 else
    g = 'F';
 return g;
}

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dhyaneshCommented:
Hi meow00,

First of all you need to accept the 3 grades as characters.

You need a function to convert these grades to integer values i.e. marks. Then only can you take average. How can you take average of say A, C, B.

The function will be just the opposite of what you have done in calcGrade where you convert average to a grade. You will have to convert grade to marks out of 100.

Then as you have done in ca

Dhyanesh

0
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

PlanetCppCommented:
dhyanesh is right i didnt even look at your calculation functions, your trying to add letters together. if you take the grades in as letters you need to convert those back to the number grades before you do any averaging
i just looked at why t was giving you weird output you still need to go back and fix the other problems
0
dhyaneshCommented:
Sorry for my last line

"Then as you have done in ca"

just ignore it.

The rest is just fine
0
itsmeandnobodyelseCommented:
That's my output now:

                                                Grade Report

Name                   Grade 1   Grade 2   Grade 3  Grade Average     Grade
BD                          75        75        85         78.3         C
DV                          85        75        75         78.3         C
JK                          65        95        45         68.3         D
EL                          45        85        75         68.3         D
AU                          45        85        65         65.0         D
AH                          95        95        95         95.0         A
AB                          85        65        75         75.0         C
MM                          95        75        85         85.0         B
KG                          65        75        65         68.3         D
BW                          75        65        65         68.3         D
BM                          65        85        65         71.7         C
RL                          85        85        75         81.7         B
RC                          65        95        85         81.7         B
CH                          75        45        85         68.3         D
LP                          85        65        65         71.7         C
MT                          85        65        75         75.0         C
AI                          75        45        95         71.7         C
AE                          45        75        95         71.7         C
CB                          95        95        95         95.0         A
SR                          65        45        45         51.7         F
SC                          45        95        75         71.7         C
MG                          95        85        65         81.7         B

Here's the code (changes in main() and PrintResults():

//  grades.cpp
//  reads a data file and creates a report (text file) from the data file
//   after some processing of the data
//  input file - grades.dat  MUST exist
//  output file - grades.txt is created and overwritten if it exists

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

// prints headings, title to output file fout
void printHeadings(ofstream & fout);

// prints all data to fout in neat format
void printResults(string, int, int, int, double, char, ofstream &);

// calculate average of 3 grades g1 g2 and g3
double calcAverage(int g1, int g2, int g3);

// determine letter grade using av
char calcGrade(double av);

enum Descriptors { INITIALS, GRADE1, GRADE2, GRADE3, Z };

int main()
{
 
  ifstream fin;// file variable for input file
  ofstream fout; // file variable for output file
  fin.open("D:\\GRADES.DAT");
  if (fin.fail())
  {
    cout << "Error opening data file , now exiting " << endl;
    return 1;
  }
  fout.open("D:\\grades.txt");  // file variable for output file
  if (fout.fail())
  {
       cout << "Error opening file for output, now exiting \n";
     return 1;
  }
 
  int grade1, grade2, grade3;  // 3 test grades respectively
  double avg;  // calculated average of 3 test grades
  string name;  // student name
  const string SENTINEL = "zzzz";  // sentinel value on file
  char grade;  // letter grade for average
  string line, gradex;

  printHeadings(fout);
  getline(fin,line);
  while (line != "zzzz" && line != "ZZZZ")
  {
     char c;
     int  n   = INITIALS;
     int  pos = 0;
     for (unsigned i = 0; i < line.length(); i++)
     {
         c = line[i];
         switch(c)
         {
         case ' ':
             {
                switch (n)
                {
                case INITIALS:
                    name = line.substr(pos, i - pos);  break;
                case GRADE1:
                    gradex  = line.substr(pos, i - pos);  
                    grade1 = (gradex == "A")? 95 :
                             (gradex == "B")? 85 :
                             (gradex == "C")? 75 :
                             (gradex == "D")? 65 :
                             (gradex == "E")? 55 :
                                              45;  
                    break;
                case GRADE2:
                    gradex  = line.substr(pos, i - pos);  
                    grade2 = (gradex == "A")? 95 :
                             (gradex == "B")? 85 :
                             (gradex == "C")? 75 :
                             (gradex == "D")? 65 :
                             (gradex == "E")? 55 :
                                              45;  
                    break;
                case GRADE3:
                    gradex  = line.substr(pos, i - pos);  
                    grade3 = (gradex == "A")? 95 :
                             (gradex == "B")? 85 :
                             (gradex == "C")? 75 :
                             (gradex == "D")? 65 :
                             (gradex == "E")? 55 :
                                              45;  
                    break;
                default:
                    break;
                }
                pos = i + 1;
                n++;
                break;
             }
         default:
             break;
         }
     }
     // fin >> grade1 >> grade2 >> grade3;
     // fin.ignore(24, '\n');
     avg   = calcAverage(grade1, grade2, grade3);
     grade = calcGrade(avg);
     printResults(name, grade1, grade2, grade3, avg, grade, fout);
     getline(fin,line);
  }
  fin.close();
  fout.close();
  return 0;
}
 
void printHeadings(ofstream & fout)
// prints headings, title to output file fout
{

  fout << setiosflags(ios::fixed | ios::showpoint);

  fout << setw(60) << "Grade Report" << endl << endl;
  fout << "Name" << setw(16) << " " << setw(10) << "Grade 1"
       << setw(10) << "Grade 2" << setw(10) << "Grade 3"
       << setw(15) << " Grade Average"
       << setw(10) << " Grade" << endl;
}
void printResults(string nm, int g1, int g2, int g3, double av,
                  char grd, ofstream & fout)
// prints all data to fout in neat format
{
  fout << nm << setw(20-nm.length()) << " " 
       << setw(10) << g1
       << setw(10) << g2 << setw(10) << g3
       << setw(13) << setprecision(1) << av
       << setw(9) << " " << grd << endl;
}
 
double calcAverage(int g1, int g2, int g3)
// calculate average of 3 grades g1 g2 and g3
{
  return double(g1 + g2 + g3) / 3 ;
}

char calcGrade(double av)
// determine letter grade using av
{
 char g; // used to store lettergrade for return value

 if (av >=90.0)
    g = 'A';
 else if (av >= 80.0)
    g = 'B';
 else if (av >= 70.0)
    g = 'C';
 else if (av >=60.0)
    g = 'D';
 else
    g = 'F';
 return g;
}

Regards Alex


0
tbell000Author Commented:
i've made the suggested corrections and i'm still looping
even when i use the suggested code ........"HELP"
0
meow00Commented:
Hello !
How does your code look like now ? Thanks
0
itsmeandnobodyelseCommented:
The while-loop

    while (line != "zzzz" && line != "ZZZZ")

ends only if there is line that has exactly one of these both strings.

if you change it to

    while (line.substr(0, 4) != "zzzz" && line.substr(0, 4) != "ZZZZ" && !file.eof())

you shouldn't get an infinite loop.

Make sure, that the last statement within loop is

      getline(fin, line);

If you have still problems, post your code again that we can look for errors.

You may copy my code above; it should compile. Then, get "grades.dat" from your posting above and store it as d:/grades.dat. If you do so, i'll bet there is no infinite loop.

Regards, Alex

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.