Solved

BAD OUTPUT TO TEXT FILE

Posted on 2003-12-09
9
422 Views
Last Modified: 2010-04-01
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
Comment
Question by:tbell000
  • 2
  • 2
  • 2
  • +2
9 Comments
 
LVL 1

Expert Comment

by:meow00
Comment Utility
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
 
LVL 6

Accepted Solution

by:
PlanetCpp earned 500 total points
Comment Utility
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
 
LVL 4

Expert Comment

by:dhyanesh
Comment Utility
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
 
LVL 6

Expert Comment

by:PlanetCpp
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 4

Expert Comment

by:dhyanesh
Comment Utility
Sorry for my last line

"Then as you have done in ca"

just ignore it.

The rest is just fine
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
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
 

Author Comment

by:tbell000
Comment Utility
i've made the suggested corrections and i'm still looping
even when i use the suggested code ........"HELP"
0
 
LVL 1

Expert Comment

by:meow00
Comment Utility
Hello !
How does your code look like now ? Thanks
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
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

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now