Solved

BAD OUTPUT TO TEXT FILE

Posted on 2003-12-09
9
434 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
  • +2
9 Comments
 
LVL 1

Expert Comment

by:meow00
ID: 9909963
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
ID: 9910021
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
ID: 9910045
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:PlanetCpp
ID: 9910109
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
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9910177
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
ID: 9911080
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
ID: 9922320
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
ID: 9922417
Hello !
How does your code look like now ? Thanks
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 9922418
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
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 be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

687 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