Solved

BAD OUTPUT TO TEXT FILE

Posted on 2003-12-09
9
425 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
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
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
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

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

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

Suggested Solutions

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

803 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