[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 441
  • Last Modified:

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?
0
tbell000
Asked:
tbell000
  • 2
  • 2
  • 2
  • +2
1 Solution
 
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
 
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 2
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now